Zastąp input type = file obrazem

102

Podobnie jak wiele osób chciałbym dostosować brzydki input type=filei wiem, że nie da się tego zrobić bez kilku hacków i / lub javascript. Ale chodzi o to, że w moim przypadku przyciski przesyłania plików służą tylko do przesyłania obrazów ( jpeg | jpg | png | gif ), więc zastanawiałem się, czy mogę użyć clickableobrazu, który działałby dokładnie jako plik typu wejściowego ( pokaż okno dialogowe i ten sam plik $ _FILE na przesłanej stronie).
Znalazłem tutaj obejście i to interesujące (ale nie działa w Chrome = /).

Co robicie, kiedy chcecie nadać styl przyciskom plików? Jeśli masz na ten temat jakiś punkt widzenia, po prostu naciśnij przycisk odpowiedzi;)

Nicolas
źródło
2
Dla wszystkich, którzy tu wylądują, warto zajrzeć również do strony tympanus.net/codrops/2015/09/15/ ... (Nie jest powiązany z tą witryną w żaden sposób, w żaden sposób ani w formie).
CBroe

Odpowiedzi:

286

U mnie to działa naprawdę dobrze:

.image-upload>input {
  display: none;
}
<div class="image-upload">
  <label for="file-input">
    <img src="https://icon-library.net/images/upload-photo-icon/upload-photo-icon-21.jpg"/>
  </label>

  <input id="file-input" type="file" />
</div>

Zasadniczo atrybut for etykiety sprawia, że kliknięcie etykiety jest takie samo jak kliknięcie określonego wejścia .

Ponadto właściwość display ustawiona na none sprawia, że ​​dane wejściowe pliku nie są w ogóle renderowane, ukrywając je ładnie i czysto.

Testowany w Chrome, ale według sieci powinien działać na wszystkich głównych przeglądarkach. :)

EDYCJA: Dodano JSFiddle tutaj: https://jsfiddle.net/c5s42vdz/

trudne
źródło
Nie jestem pewien, czy ludzie nadal uważają to za `` główną przeglądarkę '', ale wydaje się, że to nie działa w IE7
Hoppe
@Chet wygląda na to, że działa na najnowszych wersjach Safari (7+) Której wersji używasz?
hardsetting
1
@Toto Dla mnie działa w IE11, dodałem JSFiddle, więc możesz to również sprawdzić.
hardsetting
@hardsetting Masz rację! Przepraszam (być może byłem w innym trybie dokumentu, tj. 8 lub niższym)
Toto
2
przepraszam, ale myślę, że ten kod musi zostać zaktualizowany o nazwę pliku lub przynajmniej wiadomość, że plik został wybrany pomyślnie. Użytkownik nie ma żadnego wizualnego wkładu w to, co się stało po wybraniu pliku. Czy można to zrobić, proszę? Być może zmienić na inny obraz po wybraniu pliku?
JoaMika
67

Właściwie można to zrobić w czystym CSS i jest to całkiem proste ...

Kod HTML

<label class="filebutton">
Browse For File!
<span><input type="file" id="myfile" name="myfile"></span>
</label>

Style CSS

label.filebutton {
    width:120px;
    height:40px;
    overflow:hidden;
    position:relative;
    background-color:#ccc;
}

label span input {
    z-index: 999;
    line-height: 0;
    font-size: 50px;
    position: absolute;
    top: -2px;
    left: -700px;
    opacity: 0;
    filter: alpha(opacity = 0);
    -ms-filter: "alpha(opacity=0)";
    cursor: pointer;
    _cursor: hand;
    margin: 0;
    padding:0;
}

Chodzi o to, aby umieścić wejście absolutnie wewnątrz etykiety. ustaw rozmiar czcionki wejścia na coś dużego, co zwiększy rozmiar przycisku „przeglądaj”. Następnie potrzeba trochę prób i błędów, używając właściwości ujemnych left / top, aby ustawić przycisk przeglądania wejścia za etykietą.

Ustawiając przycisk, ustaw alfa na 1. Kiedy skończysz, ustaw go z powrotem na 0 (abyś mógł zobaczyć, co robisz!)

Upewnij się, że wykonujesz testy w różnych przeglądarkach, ponieważ wszystkie one renderują przycisk wprowadzania danych w nieco innym rozmiarze.

meles
źródło
Dzięki Toby, dlaczego „left: -700px;” ? W przeglądarce Firefox pole wejściowe pliku faktycznie pływa po lewej stronie strony ... nie przykleja się do zakresu etykiety ... Jeśli usunę „left: -700px;” działa dobrze
lisak
+1 Dzięki, @Sloin w lewo: -700px, ponieważ chciał, aby przycisk przeglądania znajdował się nad przyciskiem, aby kursor był wskaźnikiem, a nie kursorem tekstu.
Caleb Doucet
16

Świetne rozwiązanie dzięki @hardsetting, ale wprowadziłem kilka ulepszeń, aby działało z Safari (5.1.7) w systemie Windows

.image-upload > input {
  visibility:hidden;
  width:0;
  height:0
}
<div class="image-upload">
  <label for="file-input">
    <img src="https://placehold.it/100/000000/ffffff?text=UPLOAD" style="pointer-events: none"/>
  </label>

  <input id="file-input" type="file" />
</div>

Użyłem visibility: hidden, width:0zamiast display: nonedla problemu z safari i dodałem pointer-events: nonew imgtagu, aby działał, jeśli tag typu pliku wejściowego jest w tagu FORM.

Wydaje się, że działa dla mnie we wszystkich głównych przeglądarkach.

Mam nadzieję, że to komuś pomoże.

rishi
źródło
nie ma potrzeby dodawania style = "pointer-events: none", tworzy problem, aby otworzyć przeglądany plik.
SantoshK,
7

To jest moja metoda, jeśli rozumiem twój punkt widzenia

HTML

<label for="FileInput">
    <img src="tools/img/upload2.png" style="cursor:pointer" onmouseover="this.src='tools/img/upload.png'" onmouseout="this.src='tools/img/upload2.png'" alt="Injaz Msila" style="float:right;margin:7px" />
</label>
<form action="upload.php">
    <input type="file" id="FileInput" style="cursor: pointer;  display: none"/>
    <input type="submit" id="Up" style="display: none;" />
</form>

jQuery

<script type="text/javascript">
    $( "#FileInput" ).change(function() {
      $( "#Up" ).click();
    });
</script>
SystemDZ
źródło
6

Użyłbym SWFUpload lub Uploadify . Potrzebują Flasha, ale robią wszystko, co chcesz, bez problemów.

Każde <input type="file">oparte na nim obejście, które próbuje wywołać okno dialogowe „otwórz plik” w inny sposób niż kliknięcie rzeczywistego elementu sterującego, może zostać w dowolnym momencie usunięte z przeglądarek ze względów bezpieczeństwa. (Myślę, że w obecnych wersjach FF i IE nie jest już możliwe programowe wywołanie tego zdarzenia).

Pekka
źródło
Dzięki, też je widziałem, ale myślę, że obaj potrzebują Flash Playera do pracy, a ja nie chcę dodawać kolejnej obowiązkowej warstwy dla użytkowników. Ponadto czy jesteś pewien, że wyślą dokładnie ten sam typ danych, co pliki wejściowe? Nie chcę ponownie testować całego mojego PHP wykonanego na stronie przesyłania. Twoje zdrowie.
Nicolas
@niko nie, działają inaczej, nie są elementami formularza, ale same wysyłają plik do skryptu odbierającego, więc prawdopodobnie musiałbyś zmienić przepływ pracy skryptu. Jeśli to nie jest opcja, myślę, że nie możesz zrobić lepiej niż Shaun Inman w poście, do którego
linkujesz
W takim razie obawiam się, że to naprawdę wstyd. Czy nie ma nic na ten temat w przyszłej implementacji CSS? Mimo wszystko dzięki za odpowiedzi :)
Nicolas
@niko, nie ma za co. Dobre pytanie o CSS - właściwie nie wiem, ale HTML 5 może przynieść tutaj nowe rzeczy. Sprawdź na przykład appelsiini.net/2009/10/html5-drag-and-drop-multiple-file-upload .
Pekka
Tak, wydaje się obiecujące, nawet jeśli wersja demonstracyjna appelsiini.net/demo/html5_upload/demo.html nie wyświetla się z moim FF 3.6.3, podczas gdy mówi, że potrzebuję FF 3.6.x W każdym razie, aby wrócić do mojego problemu, obecnie HTML / CSS / Javscript (ale bez Flasha) pozwalają mi tylko na co? Jakieś czcionki i dostosowywanie „kolorów”? Czy mam rację? Twoje zdrowie.
Nicolas
4

to naprawdę proste, możesz spróbować tego:

$("#image id").click(function(){
    $("#input id").click();
});
Zicsus
źródło
3

Zamiast tego możesz umieścić obraz i zrobić to w następujący sposób:

HTML:

<img src="/images/uploadButton.png" id="upfile1" style="cursor:pointer" />
<input type="file" id="file1"  name="file1" style="display:none" />

JQuery:

$("#upfile1").click(function () {
    $("#file1").trigger('click');
});

OSTRZEŻENIE : W IE9 i IE10, jeśli uruchomisz onclick w pliku wejściowym za pomocą javascript, formularz zostanie oznaczony jako „niebezpieczny” i nie będzie można go zastąpić javascriptem, nie jestem pewien, czy można go przesłać tradycyjnie.

ParPar
źródło
2

Samo wejście jest ukryte z widocznością CSS: ukryte.

Następnie możesz mieć dowolny element, który chcesz - kotwicę lub obraz ..., po kliknięciu kotwicy / obrazu uruchom kliknięcie ukrytego pola wejściowego - pojawi się okno dialogowe wyboru pliku.

EDYCJA: Właściwie to działa w Chrome i Safari, właśnie zauważyłem, że tak nie jest w FF4Beta

Petrunov
źródło
2

Kod roboczy:

po prostu ukryj część wejściową i zrób w ten sposób.

<div class="ImageUpload">
   <label for="FileInput">
      <img src="../../img/Upload_Panel.png" style="width: 18px; margin-top: -316px; margin-left: 900px;"/>
   </label>

  <input id="FileInput" type="file" onchange="readURL(this,'Picture')" style="cursor: pointer;  display: none"/>
</div>
user3400389
źródło
2

        form input[type="file"] {
          display: none;
        }
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>

<head>
  <title>Simple File Upload</title>
  <meta name="" content="">
</head>

<body>
  <form action="upload.php" method="post" enctype="multipart/form-data">
    Select image to upload:
    <label for="fileToUpload">
      <img src="http://s3.postimg.org/mjzvuzi5b/uploader_image.png" />
    </label>
    <input type="File" name="fileToUpload" id="fileToUpload">
    <input type="submit" value="Upload Image" name="submit">
  </form>
</body>

</html>

RUN SNIPPET lub Po prostu skopiuj powyższy kod i wykonaj. Dostaniesz to, czego chciałeś. Bardzo proste i skuteczne bez javascript. Cieszyć się!!!

Neocortex
źródło
Niestety te metody nie działają dla mnie w Safari :(
czLukasss
2

W ciągu ostatniej dekady miałem wiele problemów z ukrytymi i niewidocznymi danymi wejściowymi, czasami rzeczy są o wiele prostsze, niż nam się wydaje.

Miałem małe życzenie z IE 5, 6, 7, 8 i 9, aby nie obsługiwać krycia, a zatem dane wejściowe pliku obejmowałyby przesyłany obraz, jednak następujący kod CSS rozwiązał problem.

-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
filter: alpha(opacity=0);  

Poniższe wycięte fragmenty są testowane na Chrome, IE 5,6,7,8,9,10 Jedynym problemem w IE 5 jest to, że nie obsługuje automatycznego marginesu.

Uruchom fragment, po prostu skopiuj i wklej CSS i HTML, zmodyfikuj rozmiar, jak chcesz.

.file-upload{
	height:100px;
	width:100px;
	margin:40px auto;
	border:1px solid #f0c0d0;
	border-radius:100px;
	overflow:hidden;
	position:relative;
}
.file-upload input{
	position:absolute;
	height:400px;
	width:400px;
	left:-200px;
	top:-200px;
	background:transparent;
	opacity:0;
	-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
	filter: alpha(opacity=0);  
}
.file-upload img{
	height:70px;
	width:70px;
	margin:15px;
}
<div class="file-upload">
<!--place upload image/icon first !-->
<img src="https://i.stack.imgur.com/dy62M.png" />
<!--place input file last !-->
<input type="file" name="somename" />
</div>

codedudey
źródło
1

O wiele lepszym sposobem niż pisanie JS jest użycie natywnego i okazuje się, że jest lżejszy niż sugerowano:

<label>
  <img src="my-image.png">
  <input type="file" name="myfile" style="display:none">
</label>

W ten sposób labeljest automatycznie podłączany do wejścia, które jest ukryte. Kliknięcie etykiety przypomina kliknięcie pola.

Vinyll
źródło