CSS selektory jsou moc fajn

Začal jsem si zase trochu hrát s CSS. Silnou motivací pro mě byla snaha ušetřit si práci v budoucnu. Narazil jsem na selektory a pseudotřídy v css a otevřely se mi zcela nové obzory. Už umím:

  • Vypisovat texty před obsah
  • Generovat popisky
  • Číslovat obrázky a tabulky na stránce (automaticky)
  • Udělat vytečkovaný obsah jako v knížce
  • Obarvit liché a sudé řádky tabulky

A to vše prosím bez zbytečného drbání ve zdrojáku. Hezky automaticky přes css. Tak jsem si řekl, že bych sem mohl hodit pár ukázek kódu.

::before a ::after

Pseudotřídy ::before a ::after označují oblast před nebo za elementem. Mají úžasný parametr content, který vkládá na dané místo text nebo obrázek. Obsah pole content může obsahovat i některý z atributů značky, ke které se vztahuje. Jak to vypadá:

/* Před každý odkaz vlož šipečku*/
 
a::before {content:"→";}
 
/* Za každý nadpis první úrovně dej červený vykřičník*/
h1::after {content:"!"; color: red;}

Vypisování atributů

Představme si, že bych chtěl aby se za každým odkazem objevilo v závorce, na jakou adresu vede. Nevím sice, kde by se to hodilo, ale budiž. Ten argument si můžu zavolat pomocí css.

a::after {    /*za každý odkaz*/
  content: "[" attr(href) "]";
}

Všimněte si závorek. Jak to pak dopadne s mezerami si můžete vyzkoušet v boji. Takhle si můžu vypsat i jiné atributy, třeba title. Zatím mi to nešlo u obrázku a atributu alt, ale třeba dělám něco špatně.

Vybírání pomocí atributů

Teď začíná zábava. Pomocí atributů můžu vybírat elementy na které se bude vztahovat dané pravidlo. Co abychom všechny odkazy na domovskou stránku obarvili jinak?

a[href="http://vojtahanak.cz"] {color: blue;} 

Přece bychom neradi specifikovali všechny varianty. Má tam být to http? Co když tam bude i www? Mohli bychom to zkusit tak, že by se obarvily všechny odkazy dovnitř těchto stránek.

a[href*="vojtahanak.cz"] {color: blue;}
/* * znamená, že někde obsahuje */

Jsou i další možnosti pro hledání řetězců:

a[href^="http"] {} /* vybírá odkazy, které začínají na http */
a[href$=".jpg"] {} /* vybírá odkazy, které končí na .jpg */
a[rel~="foo bar moo"] {} /* vybírá odkazy, jejichž rel je foo, bar nebo moo */
a[href^="http"][href$=".jpg"] {} /* dá se to i řetězit, tohle vybere externí jpg */

Před každým souborem ikonka

Máme seznam souborů a chceme, aby uživatel viděl, jestli stahuje pdf nebo jpg. Dáme mu tam proto ikonku.

a[href$=".jpg"]::before {content: url(jpg-icon.jpg)}
a[href$=".pdf"]::before {content: url(pdf-icon.jpg)}
/* všimněte si chybějících uvozovek */

Na tomto příkladě začíná být vidět síla css. Nepotřebuji dané odkazy označovat (ručně) další třídou. Prohlížeč sám pozná, jestli se daného odkazu pravidlo týká a obrázek si dodá zase sám. Do zdrojáku stránky pak nemusím psát další tag navíc.

Content umí vkládat jen text, atribut, obrázek nebo čítač. A s čítači to začne být opravdu zajímavé.

Číslované obrázky

Mám na stránce kupu obrázků a chci na ně uživatele odkazovat. Mohl bych je ručně očíslovat, ale nešlo by to i jinak? Abych věděl, které obrázky se budou značit, vytvořím si pro ně třídu. Zdroják bude vypadat nějak takhle.

<div class="figure">
<img src="hezky-obrazek.jpg" />
<p>Popisek obrázku</p>
</div>

Vcelku minimalistické, že (bohužel si popisku neumím vyvolat přes atribut alt). Teď ještě stylopis. Potřebujeme si zavést čítač a tomu také říci, který element na stránce bude resetovat jeho hodnotu a který ji bude zvedat. Abychom číslovali všechny obrázky na stránce, bude resetovat třeba tag body. Ten na stránce víc než jednou nebude.

/* náš čítač se jmenuje figures */
/* každý výskyt tagu body ho nastaví na nulu */
body{counter-reset: figures;} 
 
/* obalující div si zvýší hodnotu čítače o jedničku */
.figure {counter-increment: figures;}
 
/* před každým p v obalujícím divu zobrazíme nápis Obr. a hodnotu čítače */
.figure p::before{content: "Obr. " counter(figures)": "}
 
/* všimněte si jak jsou řešené mezery */

Barvení tabulek

Nemám rád čáry a linky v tabulkách. Přijde mi, že lépe vede oči, když se určité řádky podbarví. Časem jsem si zvykl mít každý sudý řádek světlejší a každý lichý tmavší. Drupal to řeší tak, že každému řádku tabulky přidělí třídu sudá nebo lichá. Jde to i snáze.

Musíme vybrat určité řádky, tedy jen některé tagy tr v každé tabulce zvlášť.

/* všechna td v prvním řádku */
tr:first-child td {background: #DDD;}
 
/* všechny buňky v prvním řádku */
/*teď se to vztahuje i na záhlaví th */
tr:first-child {background: #DDD;}
 
 
/* n-tý vnořený prvek, v závorce je výpočet pro n */
/* (3n) by vybralo každý třetí řádek */
tr:nth-child(2n) td {background: #EEE;}
 
/* liché jsou 2n+1 */
tr:nth-child(2n+1) td {background: #EEE;}
 
/* a jde to i bez matematiky */
tr:nth-child(even) td {background: #BBB;}
tr:nth-child(odd) td {background: #EEE;}
 
/* :not neguje výběr */
/* čili tr, které není sudé */
tr:not(:nth-child(2n)) td {background: #DDD;}

Šlo by použít i konstrukci nth-of-type, ale v child a type zatím dost plavu. Šlo by to dovést i k dokonalosti, kdy bychom například zobrazili číslo čítače jen pro každý pátý řádek tabulky.

No není to css úžasné? Kolik radosti dokáže přinést. Ale pak nastane peklo, až to začnete zkoušet na různé prohlížeče. Dokud zůstanete u aktuálních verzí, není problém. Ten se zjeví u různých archaických či prehistorických verzí typu IE7.

Klíčová slova: