site logo

Formulářový element - input type="file" a CSS

Formulářový prvek input type="file" je používán pro uploadování souboru na server. V článku najdete ukázky stylování tohoto prvku, použití některých atributů a popis ovládání v různých browserech.

V polovině roku 2013 byly uvedeny nové verze browserů FireFox 22 a Opera 15. Oba zobrazují formulářový prvek file podle vzoru Chrome. IE je tak poslední prohlížeč, který zobrazuje a ošetřuje prvek file způsobem starým 20 let.

Následuje několik příkladů nastavení vzhledu prvku. V prvním řádku každého příkladu najdete živý element, jeho vzhled je dán aktuálním browserem. Následují screenshoty prvku z jiných prohlížečů podle stejného stylu. Tak je možné porovnat vzhled prvku v různých prohlížečích. Dole je kód použitého stylu a komentář.

actual browser

Screenshots:

screenshot#1: formulářový element file, defaultní zobrazení v různých browserech

CSS: input {font: normal 13px Arial;}

HTML: <input type="file" name="f1" accept="image/*" multiple>

Defaultní zobrazení prvku file. Je předepsán jen font, který se projeví v browserech Chrome, Safari a Opera, v IE a FireFox se projeví jen v textu (nikoli na tlačítku). Text na tlačítku nelze změnit žádným atributem. Někdy browsery nastaví znění textu v závislosti na atributu multiple.

Browsery Chrome, Safari, FireFox a Opera zobrazují tento prvek specifickým způsobem. Tlačítko pro výběr souboru je vlevo, místo obvyklého umístění vpravo (prvky select, number, date). Chybí rámeček prvku, a to v případě bílého pozadí formuláře a nevyplněného políčka způsobí, že je viditelné jen tlačítko, jako by prvek nebyl vykreslen celý.

Tlačítko a lokalizovaný text je zbytečná komplikace. Všechny browsery (kromě IE) otevřou dialog pro výběr souboru ať kliknete kdekoli na prvek. Prvek by mohl vypadat jako běžný textbox, doplněný o ikonu adresáře vpravo v elementu.

actual browser

Screenshots:

screenshot#2: formulářový element file, zobrazení s jednoduchým CSS v různých browserech

CSS: .f2 {width: 320px; height: 22px; margin: 0;}

HTML: <input type="file" name="f2" class="f2">

V následující ukázce je předepsána šířka a výška prvku. Chrome, Safari, Firefox i Opera používají k výpočtu rozměru prvku jiný box model než browser IE. Rozměr všech prvků ve screenshotu je stejný jen díky tomu, že není vykreslen rámeček. Starší FireFox (do verze 21) umožnil nastavit šířku jen pomocí atributu size.

Chrome, Safari, FireFox i Opera zobrazí pouze název vybraného souboru. Dnes už jenom IE zobrazuje navíc i celou, obvykle velmi dlouhou cestu k souboru (asi relikt DOSu). Starším vývojářům může cesta k souboru chybět, běžného uživatele potěší. Když je vybráno více souborů (pomocí atributu multiple), Chrome, Safari, FireFox a Opera nezobrazí jména souborů, ale počet vybraných souborů, IE zobrazí naprosto nepřehledný seznam souborů vč. úplné cesty ke každému z nich.

actual browser

Screenshots:

screenshot#3: formulářový element file, zobrazení se složitějším CSS v různých browserech

CSS: .f3 {width: 320px; height: 22px; margin: 0; border: 1px solid #777;
  float: left; -webkit-box-sizing: border-box; -moz-box-sizing: border-box;}

input[type="file"].f3::-webkit-file-upload-button {
  float: right; position: relative; top: -1px; right: -1px;}

HTML: <input type="file" name="f3" class="f3" size="34">

Ve třetí ukázce se pokusíme najít takový kód, který zobrazí co nejvíce podobné prvky type="file". Do Chrome, Safari, FireFoxu a Opery přidáme rámeček a přesuneme tlačítko vpravo (ve FireFoxu neúspěšně). Prefixem pro webkit nastavíme CSS vlastnosti i pro Operu. Výsledek je na srovnávacím screenshotu.

Vyjdeme z předešlého příkladu nastavení rozměrů prvku a přidáme rámeček border: 1px solid #777. Tím dosáhneme že celý prvek v Chrome, Safari, FireFox i Opera je viditelný i na bílém pozadí formuláře. Protože Webkit a Mozila počítají rozměry tohoto prvku podle W3C box modelu a IE podle quirk modelu, sjednotíme model pomocí CSS -webkit-box-sizing: border-box a -moz-box-sizing: border-box. Prázdný prostor pod prvkem v Chrome a Safari se odstraní pomocí float: left.

Tlačítko v Chrome, Safari a Opeře pomocí selektoru -webkit-file-upload-button a float: right přesuneme na pravou stranu a upravíme jeho pozici. Bohužel místo uvolněné po tlačítku vlevo nelze využít a jméno souboru zůstane v místě kde bylo původně. Tyto úpravy stylu zvládá jen webkit, proto tlačítko ve FireFoxu zůstane vlevo.

Pro starší verze FireFoxu musela být šířka prvku nastavena pomocí atributu size="34". Tím bylo dosaženo zhruba stejné šířky prvku jako v ostatních browserech pomocí CSS vlastnosti width: 320px.

Jediný způsob jak připravit tento prvek podle vlastních představ, jednotně v různých browserech, je založen na následujícím principu: pro prvek input type="file" nastavíte úplnou průhlednost, tím se stane neviditelný, ale zachová si funkčnost tj. po kliknutí spustí dialogové okno (widget) pro výběr souboru. Přes tento průhledný prvek je položen běžný (viditelný) textbox, do kterého je zapsán název vybraného souboru pomocí javascriptu. Postup je popsán např. na webu Quirksmode. Podobný postup najdete na Viget Labs.

Ovládání formulářového prvku file

Okno pro výběr souboru se zobrazí po kliknutí na kterékoli místo prvku file, jen v IE musíte kliknout přímo na tlačítko. IE umožní procházet cestu pomocí kurzorových kláves. Zapisovat, nebo editovat název souboru, či cestu k souboru pomocí klávesnice neumožňuje žádný browser.

Browsery Chrome, FireFox a Opera umožní vybrat soubory pomocí metody drag&drop. Otevřete Windows Explorer, nebo Total Commander a požadovaný soubor přetáhnete nad element file a uvolníte tlačitko myši. Pokud je nastaven atribut multiple můžete přetáhnout více souborů najednou. IE tuto metodu nepodporuje.

Občas nastane situace, kdy potřebujete smazat obsah prvku file. Velmi jednoduchý postup nabízí Chrome a Opera: vyvoláte dialog pro výběr souboru, pak místo tlačítka OK, zvolíte storno. V IE umístíte textový kurzor do prvku a zmáčknete delete. Celý formulář jde vymazat opětovným načtením stránky (ve FireFoxu spolu s tlačítkem shift). Také je možné přidat dnes již téměř zapomenuté tlačítko reset.

Atributy formulářového prvku file


<form method="post" action="script.asp" enctype="multipart/form-data">
...
<input type="file" name="upFile" accept="image/*" multiple>
...
</form>

Použití prvku file  vyžaduje uvést v otevíracím tágu formuláře form atributy enctype="multipart/form-data"  a method="post". Atribut multipart/form-data  zkóduje formulářová data tak, aby mohla obsahovat binární data v souboru. Na serveru je nutno data nejdříve dekódovat, nelze je číst přímo pomocí Request.Form("name"), tak jak je běžné při práci s čistě textovými formuláři.

Element file může obsahovat nepovinný atribut accept, udávající přípustné typy souborů podle specifikace MIME. V dialogovém okně pro výběr souboru by se měl objevit seznam jen předepsaných typů souborů. Atribut accept  nefunguje v IE a Safari, jinde dokáže filtrovat jen některé typy souborů.

Atribut multiple umožní vybrat více souborů do jednoho formulářového prvku. Soubory se vybírají najednou. V dialogovém okně pro výběr souborů označíte všechny soubory pomocí kláves ctrl, nebo shift. Místo názvů souborů se v tomto případě zobrazí počet vybraných souborů. Atribut multiple  funguje ve všech moderních browserech, kromě IE.

Atribut value je typu readonly. Z důvodů bezpečnosti do něj nelze zapisovat a tak donutit browser k odeslání libovolného souboru. Výběr souboru musí provést uživatel. Při čtení hodnoty pomocí JavaScriptu získáme následující hodnoty: Chrome, Safari, Opera nahradí skutečnou cestu na C:\fakepath\Image1.jpg, FireFox vrátí jen název souboru bez cesty: Image1.jpg, IE vrátí úplnou cestu k souboru a zbytečně tak vystavuje část adresářové struktury klienta vnějšímu prostředí.

updated 2013-07-15