94

My problem:

Then user click the input type=file user must get the upload file + camera dialog. I'm using for this html attributes accept and capture. But on some modern devices this doesn't happen. Below there are the code examples and the table which of its works or not. Code examples are tested in Mobile Safari and Chrome.

TL;DR:

I have 5 code examples with just input type file:

1.(jsfiddle)

<input type="file" accept="image/*" capture>

2. (jsfiddle)

<input type="file" accept="image/*" capture="camera">

3. (jsfiddle)

<input type="file" capture="camera">

4. (jsfiddle)

<input type="file" capture>

5. (jsfiddle)

<input type="file" accept="image/*">

Test devices:

  • Samsung S3 (Android 4.1.2)
  • Samsung S3 (Android 4.3)
  • Samsung Galaxy Tab 2 7.0 (Android 4.2.2)
  • Samsung Note (Android 4.1.2)
  • iPhone 5 (iOS 7.0.4)
  • Nexus 4 (Android 4.4)

Table of results:

  • W(ork) - means enabled upload image dialog with camera
  • P(artially works) - means enabled upload dialog(not image only) with camera
  • N(ot work) - means only camera enabled
  • Ch - means Chrome
  • MS - means Mobile Safari

#

--------------------------------------------------------------------------------
|devices/example   | Ch 1| Ch 2| Ch 3| Ch 4| Ch 5| MS 1| MS 2| MS 3| MS 4| MS 5| 
--------------------------------------------------------------------------------
|Samsung S3/4.1    |  N  |  N  |  P  |  P  |  W  |  W  |  N  |  P  |  P  |  W  |
--------------------------------------------------------------------------------
|Samsung S3/4.3    |  N  |  N  |  P  |  P  |  P  |  N  |  N  |  P  |  P  |  P  |
--------------------------------------------------------------------------------
|Samsung Galaxy Tab|  N  |  N  |  P  |  P  |  W  |  W  |  N  |  P  |  P  |  W  |
--------------------------------------------------------------------------------
|Samsung Note      |  N  |  N  |  P  |  P  |  W  |  W  |  N  |  P  |  P  |  W  |
--------------------------------------------------------------------------------
|iPhone 5          |  W  |  W  |  P  |  P  |  W  |  W  |  Y  |  P  |  P  |  W  |
--------------------------------------------------------------------------------
|Nexus 4           |  N  |  N  |  P  |  P  |  W  |  -  |  -  |  -  |  -  |  -  |
--------------------------------------------------------------------------------

As you can see I can get only upload file + camera dialog for all browsers using

<input type="file" accept="image/*"> only. But there is no capture attribute in this case, and this worrying me and there is a problem with Android 4.3.

My questions are:

  1. Are behaviors in table true? Android 4.3 behavior is a bug?
  2. Can I trust for browsers what its will always add camera to upload dialog without capture attribute? (Please add proof links for answer)

Thanks.

P.S. Question is special, but on my site I must provide for users access to its images and camera. Also I think my table can be helpful for anybody and also I will searching for answer to and will post my answer here if nobody answer.

Alex
  • 11,115
  • 12
  • 51
  • 64
  • This question is not about javascript's API. It about browser behaviors with `input type file`. I don't want to read file. I just what user to provide access to it images/camera on my site. – Alex Feb 03 '14 at 13:18
  • Have you seen this - http://dev.opera.com/articles/view/media-capture-in-mobile-browsers/ – Ruskin Feb 03 '14 at 15:54
  • Yes. `The capture attribute is a boolean attribute that, if specified, indicates that the capture of media directly from the device's environment using a media capture mechanism is preferred`. But I want to know if my example(one of them) work without `capture`. Is this behavior steel in the future? Is there any draft/docs about this. – Alex Feb 03 '14 at 15:57
  • The use of capture is only a W3C Candidate Recommendation - so it may change and browsers may implement differently. I have not worked with capturing - but guess you need to have flash fallback - i.e. a polyfill or at least a message to users using feature detection (does modernizr detect capture?) if they cannot capture from camera. The alternative is a native app to access the camera. – Ruskin Feb 03 '14 at 16:38
  • 1
    `W3C Candidate Recommendation` is practically the stable API. Next is `W3C Recommendation` which means it will never change. `Modernizr` don't have detect for capture. Flash for mobile? It's not seriously. – Alex Feb 03 '14 at 17:11
  • Might this line in the spec lay any light? If the accept attribute's value is set to a MIME type that has no associated capture control type, the user agent must act as if there was no capture attribute. – Ruskin Feb 04 '14 at 10:20
  • I am assuming you are wrapping your test code in a form element – Ruskin Feb 04 '14 at 10:21
  • I tested all on iPhone 4 iOS 7 - 1,2 and 5 had "take photo..." 3 and 4 had "take photo or video ..." as you found. As I would expect too - as 3 and 4 are the two where you do not specify the accepts attribute. – Ruskin Feb 04 '14 at 10:50
  • What does Y mean ? (cf. iPhone 5 <--> MS 2) – Yonn Trimoreau Mar 29 '16 at 14:07
  • 1
    @YonnTrimoreau I think it means W-->Work – Alex Mar 29 '16 at 14:41
  • @Pinal Sure, I just wrote it here because I can't edit your post (too short..) and I'm quite fussy. But leave it here, it's obviously not a serious matter. – Yonn Trimoreau Mar 30 '16 at 12:34

4 Answers4

38

This is the actual answer. Just post it here for next users:

Actually, it seems that current implementations don’t rely on the capture attribute at all, but only on the type and accept attributes: the browser displays a dialog box in which the user can choose where the file has to be taken, and the capture attribute is not taken into consideration. For example, iOS Safari relies on the accept attribute (not capture) for images and videos (not audio). Even if you don't use the accept attribute, the browser will let you choose between "Take Photo or Video" and "Choose Existing" (thanks to@firt for pointing this out).

From this

EDITED 17 Feb 2016: This behavior is still active on devices.

Alex
  • 11,115
  • 12
  • 51
  • 64
  • 4
    FYI I believe if you use the multiple="multiple" attribute on iOS, mobile safari will bypass the choice and go straight to the multiple select. – tommybananas Jun 16 '14 at 19:59
  • mobile safari (MS) means mobile webkit, not only Safari in iOS. – Alex Apr 15 '15 at 15:15
  • What about on Windows tablets running Chrome? Is it a OS "feature" or browser? – JCS Jun 11 '15 at 12:07
  • @JCS I think this is browser "feature" – Alex Jun 11 '15 at 13:17
  • 1
    @Pinal, tried today on s Windows tablet running Chrome and it kept going to the gallery instead of showing the two options: take a photo or use gallery's image. – JCS Jun 11 '15 at 20:57
  • `capture="camera"`, `capture="microphone"`,`capture="camcorder"` and `capture="filesystem"` (String vlaues) [have been replaced in the spec](https://addpipe.com/blog/correct-syntax-html-media-capture/) with `capture="capture"` (Boolean) because the values were overlapping in functionality (and could easily be conflicting) with the well established `accept` values. – octavn Nov 09 '16 at 17:19
  • 6
    @Pinal this answer is no longer correct. iOS 10.3.1 has changed to conform to the spec, and now using capture will bypass the choice to choose images from the photo library. For example, see https://stackoverflow.com/questions/43396109/ios-update-to-10-3-1-breaks-html-input-element – David Apr 23 '17 at 22:16
  • NOTE: Enable browser permissions for example on android/firefox : Settings > Application Manager > Firefox > Permissions > "Enable Camera" – jmunsch Dec 14 '18 at 16:46
33

The "correct" code and the one you should be using is the 5th one:

<input type="file" accept="image/*">

Which is why it's working correctly on most of your devices. The above code is correct, complete and enough to tell both iOS and Android that:

  1. you want to capture an image (use accept="video/*" for video and accept="audio/*" for audio, skip altogether to allow anything).
  2. the user should be able to select an existing one OR capture it on the spot
  1. Can I trust for browsers what its will always add camera to upload dialog without capture attribute?

Yes.

The capture attribute is NOT used to include the camera option in the dialog (<input type="file"> is enough for that) but to indicate that direct capture from the webcam is preferred. From the W3C Recommendation spec:

The capture attribute is a boolean attribute that, if specified, indicates that the capture of media directly from the device...is preferred.

capture is supported by Android 3.0+ which will take you straight to the camera app if capture is present in the code.

There's no support in iOS6-10 who will always give you at least 2 options: "Take Photo" + "Photo Library".

The capture attribute has evolved in the spec (which is why you'll see several versions throughout StackOverflow):

  1. July 2010: accept="image/*;capture=camera"
  2. Apr 2011 : capture="camera" (String)
  3. Dec 2012: capture (Boolean, W3C Candidate Recommendation,)

PS: I've done a ton of research on HTML Media Capture, see Correct Syntax for HTML Media Capture and The New Prompt for Media Capture in iOS9. Here's my test bench with 20+ code combinations.

octavn
  • 3,154
  • 32
  • 49
  • Wrong answer. I didn't want to capture an image. I wanted to provide camera access and file upload access for user. And the right answer is "capture attribute doesn't make sense at all for this". – Alex Nov 09 '16 at 17:51
  • 1
    The quoted code gives you both camera access and file upload access for user. Use `capture` when you want *only* camera access (for now works only on Android). – octavn Nov 09 '16 at 19:30
  • I've updated my reply to include the *audio*, *video* and *everything* options (just remove the `accept="image/*"` part to allow *everything*) – octavn Nov 10 '16 at 17:35
  • NOTE: Enable browser permissions for example on android/firefox : Settings > Application Manager > Firefox > Permissions > "Enable Camera" – jmunsch Dec 14 '18 at 16:45
21

For others to reference this is the behavior of Chrome on Android 9 as of today (Feb 2020):

  Must be selected from album
  <input type="file" accept="image/*">
 
  Must be captured from camera
  <input type="file" accept="image/*" capture="">
 
  Allowed user to choose either from album or camera
  <input type="file" accept="image/*;capture=camera">
Beeno Tung
  • 1,058
  • 10
  • 17
  • 2
    Nice up-to-date answer with accept="image/*;capture=camera"; this is not even mentioned on developers page (https://developers.google.com/web/fundamentals/media/capturing-images) – Dat Pham Tat Apr 23 '21 at 10:17
0

in Angular 13 with Bootstrap5 only put something like that; accept=".mpeg, .MPEG, ./*"