The HTML capture attribute
The HTML capture attribute asks a file input to use the device's camera or microphone. Add capture="environment" for the outward-facing camera or capture="user" for the user-facing one, plus accept="image/*". Mobile browsers support it, but no desktop browser does.
Overview
The HTML capture attribute lets a file input ask for new media straight from a camera or microphone. It is defined for an <input> with type="file" by the W3C HTML Media Capture specification, a Recommendation since February 2018, rather than by the HTML standard.
Support starts at Chrome on Android 25, Firefox for Android 79, Safari on iOS 10 and Samsung Internet 1.5, and no desktop browser has it.
The value says which way the camera or microphone should face. The keyword user asks for the one facing the user, and environment for the one facing outward. Both are only hints, and a missing or unknown value leaves the choice to the browser.
When accept names a type that no capture control handles, the browser must act as if capture were absent. The older boolean form, a bare capture, gets the browser's default facing mode under the spec, though validator.nu rejects it.
Syntax
<label for="receipt">Photo of the receipt</label>
<input type="file" id="receipt" name="receipt"
accept="image/*" capture="environment">
Values
| Value |
|---|
| user (faces the user) | environment (faces outward) |
Example
<p style="margin-top:0">Choose or take a photo to see the file the page receives.</p>
<label for="receipt">Photo of the receipt</label><br>
<input type="file" id="receipt" name="receipt" accept="image/*" capture="environment">
<p id="msg" role="status" style="overflow-wrap:anywhere">No photo yet.</p>
<div id="preview"></div>
<script>
const input = document.getElementById('receipt');
const msg = document.getElementById('msg');
const preview = document.getElementById('preview');
input.addEventListener('change', function () {
preview.replaceChildren();
const file = input.files[0];
if (!file) {
msg.textContent = 'No photo yet.';
return;
}
msg.textContent = file.name + ', ' + (file.type || 'no type') + ', ' + file.size + ' bytes';
const img = document.createElement('img');
img.alt = 'Preview of ' + file.name;
img.height = 64;
img.style.cssText = 'max-width:100%;object-fit:contain';
img.src = URL.createObjectURL(file);
img.addEventListener('load', () => URL.revokeObjectURL(img.src));
preview.append(img);
});
</script>
Best practices
- Add
captureonly when new media is what you want, such as a photo of a receipt. Withaccept="image/*"alone, a browser could offer the camera or the photo collection. - Set capture in the HTML or with
setAttribute('capture', 'environment'), so the attribute is there in every browser. Desktop Chrome and Firefox have no capture property, andinput.capture = 'user'only adds a plain JavaScript property there. - Use
getUserMedia()when you need a live preview or control over the camera, which capture doesn't offer. - Strip location data from photos before you publish them. A location stored in metadata such as EXIF might reveal more than the user expects.
Frequently asked questions
What do capture=user and capture=environment mean?
Why does the capture attribute open a file picker on my laptop?
Does capture need the accept attribute?
Can the capture attribute force users to take a new photo?
Is a photo taken with capture saved to the device?
input.files, and keeping it is up to your code.How can I check whether a browser supports capture?
'capture' in document.createElement('input'), because the property has the same mobile-only support as the attribute.






















