Klonované submity útočí (jednotný vzhled odesílacího tlačítka pomocí CSS)
Potřebujete někdy nastylovat odesílací tlačítko ve formuláři v rozměrech a na pozici pixelově perfektních? Mám pro vás řešení. Není jednoduché, obsahuje magii, které nerozumím, a nefunguje dokonale ve všech prohlížečích. :-)
Ještě čtete? Dobře děláte, protože na druhou stranu je široce použitelné a vůbec ho mám rád tak ušmudlané jaké je, protože mě od té doby už několikrát pomohlo.
Navíc — proč na sebe dělat ramena jak moc věcem rozumíme? Sám bych docela rád četl texty ne jen mentorské, ale také ty s jistou pochybností na straně autora. Nejistota má tu výhodu, že do řešení problému vtahuje i čtenáře.
Pokud vás detaily nezajímají, podívejte se na výsledek rovnou.
Že weby nemusejí vypadat ve všech prohlížečích stejně? Ano, obecně tomu tak je, ale vezměme konkrétní situaci, kdy se nad jednotným řešením rozhodně vyplatí přemýšlet:

Je docela dobře možné, že když chcete nastylovat vzhled odesílacího tlačítko a nedělat si těžkosti s jeho rozměry, použijete obvykle tento CSS kód. Ostatně, dělal jsem to dříve stejně:
.submit {
padding: 5px 10px;
font: 12px/18px sans-serif;
background: red;
color: white;
border: 1px outset #F30;
}
Tlačítko vypadá docela hezky. Zdánlivě jej máme pod kontrolou, prima. Jenže problém nastane, když je umístěno v layoutu, který je citlivý na rozměry elementů, jako je ten na prvním obrázku. Podívejme se jak bude tlačítko popsané našim pravidlem vypadat v různých prohlížečích.
Zelený poloprůhledný obdélník značí oblast, kde jsme s dosavadními znalostmi očekávali umístění tlačítka a v jaké jsme si představovali jeho rozměry:
Vidíte to co já? Jediný prohlížeč, který splnil naše naděje, je Internet Explorer 8. To bolí! Pixel-perfect rozměry tlačítka potřebujeme obvykle v situacích, kdy jej zarovnáváme s vedle umístěným textovým vstupem a tak situace, kdy všechny ostatní prohlížeče vypočetly trochu jinou výšku je blbá, blbá a co si budeme povídat: blbá!
V layoutu z prvního obrázku by tlačítkové rodeo našich prohlížečů přivodilo nemilou událost v kodérově duši.
Proč nám to ty zlé prohlížeče dělají?
Než si řekneme jak situaci alespoň zčásti zachránit, musíme pochopit jak prohlížeče s formulářovými prvky zacházejí. Stručně řečeno: podle konvencí operačního systému a podle vlastního uvážení. Formulářové prvky jsou specifikací vnímány jako součást uživatelského rozhraní operačního systému a podle toho se prohlížeče také chovají.
Příklad za všechny: rozměry formulářových elementů prohlížeče nepočítají podle box modelu daného specifikací (rozměry obsahu), ale podle tradičního (quirks) box modelu (rozměry obsahu + rozměr vnitřního okraje + rozměr rámečku). (V řeči CSS se na formulářové elementy aplikuje deklarace box-sizing: border-box, na ostatní pak box-sizing: content-box) A tak v hodnotách vlastností width a height musíte započíst rámeček (border) a vnitřní okraj (padding), i když vám prohlížeč běží ve striktním režimu.
Magie vs. „vědomosti” a „racionalita”: Do boje!
Dejme se do úprav tlačítka. Zde poslední varování jedincům se slabším zažíváním — řešení některých dále zmíněných problémů spadají do oblasti magie. Racionální vysvětlení autorovi článku v těchto případech nejsou známa. Pokud znáte podstatu odchylek v jednotlivých prohlížečích, neváhejte prosím použít komentářů.
Internet Explorery verzí 6 a 7 vykreslují v tlačítku vnitřní prostor. To způsobuje deklarace overflow: hidden, kterou mají v přednastaveném stylopisu. Řešením je každopádně resetování vlastnosti overflow na hodnotu visible.
.submit_better {
padding: 5px 10px;
font: 12px/18px Arial, sans-serif;
background: red;
color: white;
border: 1px outset #F30;
overflow: visible;
}
Jdeme dál — opravíme výšku elementu ve Firefoxu 3.6 a Opeře 10. Jak už je zmíněno výše, všechny testované prohlížeče počítají výšku formulářových prvků tradičním způsobem, tedy započítávají rámeček (border) i vnitřní okraj (padding). Tomu odpovídá deklarace box-sizing: border-box, kterou najdete v jejich přednastavených stylopisech. Jenže FF3.6 a Op10 i tak dojdou k jiným číslům.
Obecně následující postup nedoporučím, ale dobře, pomůžeme si silou — explicitním nastavením výšky našeho tlačítka. Podle vzorečku pro výpočet výšky v tradičním (quirks) box modelu ji získáme jako výšku řádku (18px) sečtenou s vertikálním vnitřním okrajem (padding) (2 * 5px) a s vertikální rámečkem (border) (2 * 1px). Tedy 30 pixelů.
.submit_better {
padding: 5px 10px;
font: 12px/18px Arial, sans-serif;
background: red;
color: white;
border: 1px outset #F30;
overflow: visible;
height: 30px;
}
Předposlední problém — dvoupixelový vnější okraj (margin) ve Webkitu navíc — vyřešíme jeho vynulováním. Příčina? Opět mě není přesně známa. Chrome Developer Tools nám sice v například dvoupixelový margin u input[type=submit] ukáží v „Computed Style”, nicméně po jeho původu není vidu ani slechu nejen v „user agent stylesheet” tamtéž, ale ani v přednastaveném stylopise ve veřejném repozitáři Webkitu. Co vy na to, agente Muldere? Dalším krokem tedy bude vynulování marginu:
.submit_better {
padding: 5px 10px;
font: 12px/18px Arial, sans-serif;
background: red;
color: white;
border: 1px outset #F30;
overflow: visible;
height: 30px;
margin: 0;
}
Jdeme na problém poslední — vnitřní okraj (padding) navíc ve Firefoxu 3.6. Když se podíváte do jeho přednastaveného stylopisu pro formuláře (na MacOS v /Applications/Firefox.app/Contents/MacOS/res/forms.css), najdete tam pravidlo podobné tomuto:
input[type="submit"]::-moz-focus-inner {
padding: 0px 2px 0px 2px;
}
Firefox pak elementu, kde očekává outline (zvýraznění focusovaného prvku) vykresluje tento vnitřní okraj navíc. Zbavme se ho. K našemu pravidlu přidáme tedy ještě jedno:
.submit_better {
padding: 5px 10px;
font: 12px/18px Arial, sans-serif;
background: red;
color: white;
border: 1px outset #F30;
overflow: visible;
height: 30px;
margin: 0;
}
.submit_better::-moz-focus-inner {
padding: 0;
}
Hotovo! Aktuálně se naše tlačítko zobrazuje na očekávané pozici a v očekávaných rozměrech v IE8, FF3.6, Chrome 7, Safari 5. Tlačítko je mírně větší v IE7 a ještě trochu více v IE6, ale způsobem, který nijak zásadně neohrožuje ani layout uvedený v prvním obrázku.
Výsledný test-case ještě jednou >
Na závěr ještě malé šťouchnutí — všimli jste si několika v článku hned několika referencí na přednastavené stylopisy prohlížečů (user agent stylesheets)? Přátelé, ty jsou pravým kodérským pokladem. Pokud z něj chcete vidět další perličky, nalaďte si Twitter autora.
