13

Just want to the style of:

<input type="file" value="Choose the file" />

looks like:

<a href="#">Choose the file</a>

just using css.

Is it possible?

Freewind
  • 193,756
  • 157
  • 432
  • 708

5 Answers5

22

How about using label instead of anchor and you connect the label with input[type="file"] via for:

label{
  color: blue;
  cursor: pointer;
}

label:hover{
  text-decoration: underline;
}

#file_input_id{
  display:none;
}
<label for="file_input_id">I'm a wannabe link</label>
<input type="file" id="file_input_id">

Note: safari has issues with using display:none to input[type="file"]

Community
  • 1
  • 1
Vucko
  • 20,555
  • 10
  • 56
  • 107
  • 3
    There are very clever hacks and workarounds in this thread, but this is by far the most elegant answer IMO. – John Weisz Dec 11 '14 at 09:35
  • 2
    I've always had problems with styling `input[type="file"]` and this solution is the best for it, IMHO. – Vucko Dec 11 '14 at 09:37
  • Yeah, this is the correct answer. Sticking with form elements; clean and simple. No hacks needed. – misterManSam Dec 11 '14 at 09:46
  • This is definitely the way to go if you only want the appearance of a link, without any extraneous UI – SW4 Dec 11 '14 at 09:52
10

It will likely require some fine tuning for the size, hover state etc, but why not do:

span {
  cursor: pointer;
}
a {
  position: relative;
  overflow: hidden;
}
span:hover a {
  color: red;
}
a + input {
  position: absolute;
  top: 0;
  left: 0;
  opacity: 0;
}
<span><a href='#'>Link!</a><input type='file' /></span>

The basic premise is that the input type=file should be absolutely positioned over the link with its opacity set to zero so it still traps the normal user interaction behaviour.

David Mihal
  • 944
  • 6
  • 23
SW4
  • 69,876
  • 20
  • 132
  • 137
1

You can add a label linked to the input (and you should for accessibility anyway, especially as you really need to hide the input). Then you can set the opacity of the input to 0 and make it position:absolute so that it does not affect the page. You could hide it, but I think some browsers will not trigger the label functionality, so you won't be able to choose a file.

You can then style the label how you want, or even wrap it in an a tag so it will behave exactly like the other links on your page.

The disadvantage of hiding the input is that you will not be able to see the chosen file. If you need to do that you can show it in the label with a simple bit of jquery:

$('input[type="file"]').change(function() {
  // find the label for the currrent file input 
  $('label[for="' + this.id + '"]').text('Choose the file - ' + $(this).val());
});
input[type=file] {
  position: absolute;
  top: 0;
  right: 0;
  filter: alpha(opacity=0);
  opacity: 0;
  margin: 0;
  padding: 0;
}

a > label {
  /* inherit the hand cursor from the a tag */
  cursor:inherit;
}

a:hover {
  color:red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form action="#">
    <input id="thefile" type="file" value="Choose the file" />
    <a href="#"><label for="thefile">Choose the file</label></a>
</form>
Rhumborl
  • 16,349
  • 4
  • 39
  • 45
0

You can try using this "dirty" hack:

input {
    opacity: 0;
    position: relative;
    left: -100px
}

http://jsfiddle.net/1apggx8q/

0

Here is another solution similar to the above but I separate the input tag and show the link instead.

div.fileinputs {
    position: relative;
}

div.fakefile {
  position: absolute;
  top: 0px;
  left: 0px;
  z-index: 1;
}

input.file {
  position: relative;
  text-align: right;
  -moz-opacity:0 ;
  filter:alpha(opacity: 0);
  opacity: 0;
  z-index: 2;
}

And the html

<div class="fileinputs">
  <input type="file" class="file" />
  <div class="fakefile">
    <a href="">browse file</a>
  </div>
</div>

Here is the fiddle

Pramod Solanky
  • 1,690
  • 15
  • 17