11

I'd like to have a styled file input field on my page and therefore put it inside a button which it completely covers and made it invisible by setting its opactiy to 0.

This approach works pretty well in the latest version of Chrome but Firefox (and IE) won't open the file dialog when clicking the button:

http://jsfiddle.net/ch8xxvez/3/

<button style="width: 100px; height: 100px; position: relative;">Upload button
    <input type="file" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; opacity: 0;"></input>
</button>

The same code works if I replace the button element with a div but I'd really like to know if there is a way to make this work with the button tag in the latest versions of IE (>= 10), FF, Chrome & Edge.

suamikim
  • 5,350
  • 9
  • 40
  • 75
  • 1
    That this works at all is fairly surprising: it shouldn't, the HTML is wrong. Put it in a div or similar element, make the file input `opacity: 0;`, and style the div/similar element, that is the simplest way to do what you're trying to do. Don't put form input elements inside other form input elements, it doesn't make any logical sense. – DanCouper Oct 29 '15 at 17:11
  • 1
    Possible duplicate of [span inside button, is not clickable in ff](http://stackoverflow.com/questions/14689879/span-inside-button-is-not-clickable-in-ff) – BSMP Oct 29 '15 at 17:26

5 Answers5

16

Input elements are not allowed inside button elements in HTML.

Write valid HTML instead of depending on consistent error recovery.

Make the button and input sibling elements and then position them within a container (such as a div).

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
4

try it

https://jsfiddle.net/DeivissonSedrez/0z6mq5yk/1/

<div class="fakeButton">Upload button
        <input type="file" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; opacity: 0;"></input>
</div>
    <style>
        .fakeButton{
            width: 100px; 
            height: 100px; 
            position: relative; 
            border:1px solid #000; 
            border-radius:3px; 
            text-align:center; 
            font: 15px arial; 
            line-height:90px;
            box-shadow: inset 0 2px 3px 0 rgba(255,255,255,.3), inset 0 -3px 6px 0 rgba(0,0,0,.2), 0 3px 2px 0 rgba(0,0,0,.2);
            background-image: -webkit-linear-gradient(#EEEEEE, #D8D8D8 130%);
            background-image: -moz-linear-gradient(#EEEEEE, #D8D8D8 130%);
            background-image: -o-linear-gradient(#EEEEEE, #D8D8D8 130%);
            background-image: linear-gradient(#EEEEEE, #D8D8D8 130%);
        }
    </style>

I put the input inside a div and made a div look like a button with css

They worked in my tests on IE, FF and Chrome

I hope it helps

Deivi
  • 197
  • 2
  • 12
3

According to W3 specification of the BUTTON tag, you cannot inset the following tags inside a <button> tag:

  • A
  • INPUT
  • SELECT
  • TEXTAREA
  • LABEL
  • BUTTON
  • FIELDSET

However, all the other block and inline tags are allowed.

jehna1
  • 3,110
  • 1
  • 19
  • 29
1

It is not valid to have an <input> inside a <button>. Consider putting it inside a <label> instead, or a <span> with a click handler and suitable CSS or use anchor tags.

Saransh Kataria
  • 1,447
  • 12
  • 19
1

I am not sure that you can do this as the W3C spec says you can not have interactive content (i.e. clickable content) inside a button.

Content model: Phrasing content, but there must be no interactive content descendant.

This question at least in context is also a possible duplicate of this of which the answer here is accredited.

DavidT
  • 2,341
  • 22
  • 30