Stylování formulářů snadno a rychle

Tue, 15 Dec 2020 19:09:51 +1100

Než si dáme další článek z dílny seriálového kritika, proložím své recenze jedním z oboru. Takový už jsem nepsal ani nepamatuji, ale snad si vzpomenu, jak se to dělá. A protože mé návody byly vždy cílené na kodéry začínající a mírně pokročilé, vezmu si pod lupu stylování formulářů. Úplné základy.

Je to nutné zlo, které člověk musí trpět poměrně často. Ale technologie pokročily, takže se s tím dá poprat velice snadno i bez použití složitých frameworků. Ty buď máte zvládnuté a neřešíte nic, nebo vám činnost spíš zkomplikují. U formulářů to platí dvojnásob.

Základní resety

Relativní jednotky zatím řešit nebudeme. Hezky všechno v pixelech, ať v tom nedělám ještě větší zmatky.

* {
	border:0;
	margin:0;
	padding:0;
	-webkit-box-sizing:border-box;
	box-sizing:border-box;
}
:focus {outline:none;}

button,
input,
textarea,
select {
	-webkit-appearance:none;
	-moz-appearance:none;
	appearance:none;
	border-radius:0;
}

Appearance je nejdůležitější vlastnost, které je třeba se zbavit, ať nám to neblbne na telefonech a iOS zařízeních. A pak můžeme úplně v klidu nastavit globální styl pro základní formulářové prvky. Dřív platilo, že hvězdičkový reset na formulářové prvky ne. To už naštěští nějakou dobu nemusíme řešit, takže ušetříme spoustu zbytečností ve stylech.

Nesmíme zapomenout nastavit kompletní vlastnosti fontu. Tohle bohužel mnohé prohlížeče neumí zdědit z body. Stejně tak box-sizing: nemáme-li ho v resetu, je potřeba nastavit pro uvedené elementy. Pro textareu zvedneme výšku a omezíme resize na směr i hodnoty.

body,
input,
textarea,
select,
button {
	font:400 16px/1.5 Arial,Helvetica,sans-serif;
}

input:not([type="radio"]):not([type="checkbox"]),
select,
textarea {
	display:block;
	color:#000;
	padding:10px 15px;
	height:50px;
	width:100%;
	border:1px solid #e1e1e1;
	/*
	-webkit-box-sizing:border-box;
	box-sizing:border-box;
	*/
}

textarea {
	height:200px;
	min-height:100px;
	max-height:1000px;
	resize:vertical;
}

A to je k základním prvkům vše. Všimněte si, že základní pole nemám jako výčet hodnot, ale jako výjimku ze všech. HTML5 nám nabízí mnohem vyšší škálu typů, než jenom [text] a [password].

Tlačítko si pak můžeme upravit jakkoli uznáme za vhodné, já ho vykreslím jen jako šedý obdélník. Pod tag ho mám vnořené cíleně, protože grafik nám často naplánuje různě vypadají buttony pro formulář a mimo něj.

form button,
form input[type="submit"] {
	cursor:pointer;
	background:#e1e1e1;
	transition:.25s;
	min-width:100px;
	border:0;
	height:50px;
}
form button:hover,
form input[type="submit"]:hover {
	background:#888;
	color:white;
}

Placeholder

Než nám moderní technologie povolily atribut placeholder, museli jsme výchozí hodnoty složitě měnit JavaScriptem. Nyní je ale vše mnohem jednoduší, snad s výjimkou stylování. Tam malý zádrhel je. Vlastnosti musí být zapsané tak, jak je mám na následující ukázce. Pokud totiž vše zapíšeme za sebe s čárkou, IE Edge nás s tím pošle do háje. Takže pro každý prefix jedna ukončená definice.

textarea::placeholder,
input::placeholder {color:#e1e1e1;}

textarea:-ms-input-placeholder,
input:-ms-input-placeholder {color:#e1e1e1;}

input:not([readonly]):not([disabled]):focus,
textarea:not([readonly]):not([disabled]):focus {border-color:#a1a1a1;}

Grafický selecbox

Další problematický prvek je selectbox. V minulosti bylo potřeba na jeho složitější vykreslení povolat JavaScriptovou knihovnu, nyní se však obejdeme bez ní. Pokud ale potřebujeme komplexnější prvky uvnitř drop-down nabídky, čistým stylováním to bohužel nezvládneme. JS knihoven jsem vyzkoušel větší množství, ale nakonec jsem vždy došel k závěru, že je lepší, když si to prostě napíšu sám. Žádná není na 100 % dokonalá. U každé narazíme na nějaké bugy, či události, které neumí. Nejnovější knihovnička mi zabrala asi 3 hodiny, což zhruba odpovídá času, který bych strávil studiem a debugováním nějakého hotového řešení... Často je lepší, když si to člověk napíše sám.

Ale zpět ke stylování klasického selectu. Jediné omezení, které musíme překousnout, je nemožnost upravit samotný drop-down. Jediné, k čemu nás prohlížeče pustí, je velikost písma a barvy.

Hlavní select se dá ovšem nastylovat se vším všudy, bez jakýchkoli problémů. Pokud stále řešíme IE 11, definici backgroundu je nutné rozepsat, protože IE 11 ji nepochopí, když obsahuje funkci calc(). A já raději použiju calc, než abych naschvál ukládal png obrázek s bílým místem, kvůli marginu.

form select {
	padding-right:50px;
	cursor:pointer;
	background:url(select.png) no-repeat;
	background-position:calc(100% - 15px) 50%;
	background-size:20px auto;
}
form select option {
	font-size:110%;
	color:#013be0;
}
form select option:hover {
	background:#013be0;
	color:white;
}
form select::-ms-expand {
	display:none;
}
form select:focus {
	border-color:#a1a1a1;
	color:black;
	text-shadow:0 0 0 #000;
	font-weight:400;
}

Grafický checkbox a radio

Ani zde není potřeba volat JavaScript a stylovat prvky pomocí nastrčených spanů. Valná většina moderních prohlížečů umí vykreslit základní styly pro checkbox i radio správně, výjimkou budiž jen Internet Explorer 11. Ale ani on není extra pozadu; "škaredě" vykreslí pouze puntík, respektive fajfku při stavu :checked.

form input[type="radio"],
form input[type="checkbox"] {
	margin:0 15px 0 0;
	font-size:24px;
	width:1em;
	height:1em;
	border:2px solid #e1e1e1;
	border-radius:0;
	display:inline-block;
}
form input[type="checkbox"]:checked {
	border-color:#013be0;
	background:url(checkbox.png) no-repeat 50% 50%/80% auto;
}

form input[type="radio"] {
	border-radius:50%;
	background:url(radio.png) no-repeat -100px 50%/50% auto;
}
form input[type="radio"]:checked {
	border-color:#013be0;
	background-position:50% 50%;
}
form label.radio,
form label.checkbox {
	display:flex;
	align-items:center;
}

Není to vůbec nic složitého: nějaké barvy a obrázky, zarovnání a odsazení, a máme hotovo. Pokud chceme stejně hezké prvky i pro zmiňovaný IE 11, je potřeba přidat pomocné spany, ale i tady se úspěšně vyhneme JS obsluze. Stačí přidat pár CSS definic pro posloupné prvky. To už si ale prohlédněte na přiložené ukázce.

Závěrem: přístupnost na prvním místě

Na závěr bych ještě rád zmínil jednu věc, kterou vídám v poslední době stále častěji. Mám na mysli různé "cool" efekty, které mají formuláře takříkajíc zkrášlit. Máme label, který je vepsaný přímo přes textové pole a supluje funkci placeholderu. Na focus popisek vyjede nahoru přes definovanou transition. Určitě už jste to někdy viděli. Funkce je to sice pěkná, ale zoufale nepraktická... Problém nastává ve chvíli, kdy nám prohlížeč automaticky jednotlivá pole vyplní. JavaScript totiž neumí univerzálně detekovat tuto událost, a tak se nám může stát, že label je překrytý přes hodnotu v poli. To sice lze vyřešit několika způsoby, ale my bychom si spíš měli položit otázku: proč bych měl tohle vůbec ladit?

Jako uživatel chci formulář přehledný a jednoduchý, jako kodér chci formulář... můžete hádat, jaký. Není formulář v příloze sympatičtější, než nějaká pekelná monstra, co vám třikrát obletí svět, než vás pustí k vyplnění?

Ukázka: form.html