25. 10. 2010

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.

Výsledný test-case >

Ž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:

Přihlášení k newsletteru na www.festival.cz

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.

Komentáře

Tagy: css články

blog comments powered by Disqus

Veřejná školení
Webexpo Academy, Praha

HTML5 & CSS3
29/5
Mobilní
webdesign
18/6