CSS3 – nahrazovaný a generovaný obsah

20. července 2005

První verze kaskádových stylů nenabízela žádné možnosti, jak do výsledné zobrazené podoby dokumentu vkládat informace (texty, počítadla, obrázky), které nejsou jeho součástí. CSS2 nakročila k vylepšení tohoto stavu umožněním vkládání dodatečných dat před a za element. Chystané CSS3 pokračuje dále v tomto trendu – bude umožňovat velmi rozsáhlou a precizní kontrolu nad generovaným a nahrazovaným obsahem elementů.

Generování obsahu dokumentu v kaskádových stylech

Možnostmi nahrazování a generování obsahu elementu se zabývá modul Generated and Replaced Content. Jako většina jiných je zatím ve stavu pracovního návrhu. Oproti těmto dokumentům ve stejném stádiu rozpracování je poměrně nehotový a lze předpokládat, že se ještě bude dost měnit. I tak si z něj ale lze udělat slušný obrázek o tom, jaké nové možnosti s ním dostanou webdesignéři do rukou.

Vkládáme obsah okolo elementu

Kaskádové styly druhé generace přinesly možnost vkládat generovaný obsah před a za element pomocí pseudoelementů :before a :after a vlastnosti content.

V CSS3 je nyní nově možno tyto pseudoelementy řetězit, a to hned dvěma způsoby. Buď lze použít zřetězení ::before::before (jak již bylo uvedeno dříve, identifikátor pseudoelementu nyní nově předchází dvě dvojtečky), nebo novou syntaxi ::after(n), kde n je přirozené číslo. Tyto zápisy jsou interpretovány lehce odlišně, hlavně v tom, jak jsou jednotlivé elementy vkládány do sebe.

Zcela nový je pseudoelement ::outside. Představuje imaginární element obalující svůj cíl. Pokud bychom potřebovali určitý element obalit do jiného (bez syntaktického významu), můžeme jej buď v dokumentu vložit do elementu div, nebo tento element vytvořit pro potřeby zobrazení na úrovni kaskádových stylů:

p.obaleny_element::outside
{
  border: 1px dotted red;
  padding: 10px;
}

Výhodou je, že tento pseudoelement dědí hodnoty vlastností ze svého cílového elementu a nikoli z rodiče, jak by to bylo při obalení elementu přímo ve zdrojovém dokumentu.

Číslujeme řádky

Mějme element, který slouží k zobrazování části kódu:

div.code
{
  white-space: pre;
}

Nyní chceme, aby jednotlivé řádky byly číslované, zobrazený kód tak bude pro uživatele mnohem přehlednější a mnohem jednodušeji se bude odkazovat na konkrétní řádky. Jedinou možností, jak docílit tohoto chování v CSS2, je vložit každý řádek kódu do elementu, který v CSS zvyšuje počítadlo a zobrazuje jej před svým obsahem (tedy prakticky jde o položku číslovaného seznamu), což není zrovna elegantní řešení.

CSS3 proto přichází s novým pseudoelementem, ::line-marker. Jde o značku, která se formátuje stejným způsobem jako značky u položek seznamu, ale narozdíl od nich se zobrazí před každým řádkem přiřazeného elementu, nikoli pouze před prvním. Počítadlo pro náš element lze pak nadefinovat velmi jednoduše:

div.code
{
  white-space: pre;
  counter-reset: pocitadlo;
}
div.code::line-marker
{
  width: 5em;
  text-align: left;
  counter-increment: pocitadlo;
  content: counter(pocitadlo) „:“;
}

Každý marker řádku je tvořen počítadlem, které automaticky zvýší (automaticky generovaná počítadla byla uvedena již v CSS2). Samotný element obsahující ukázkový kód toto počítadlo na začátku vynuluje, takže má řádky číslované opět od jedničky.

Nahrazujeme obsah elementu

Kaskádové styly ve své třetí verzi také přebírají vládu nad nahrazovanými elementy (například element img v XHTML). Zatím se věc měla tak, že prohlížeč o daném jazyce věděl, které elementy jsou nahrazované a čím je má nahradit. Například o již zmíněném elementu img měl informace, že jej má nahradit obrázkem definovaným pomocí atributu src, případně že má použít obsah atributu alt, pokud není daný obrázek k dispozici nebo má uživatel jeho zobrazení zakázáno. Tohoto chování šlo dosáhnout, protože prohlížeč znal jazyk XHTML. Pokud byste si však chtěli vytvořit vlastní aplikaci XML, nijak byste jej nedonutili, aby některé její elementy nahrazoval z jiných zdrojů.

Ve druhé verzi stylů bylo možno použít vlastnost content pouze k vytvoření obsahu pseudoelementů ::before a ::after. V CSS3 však lze použít tuto vlastnost i přímo na elementy a definovat tak jejich obsah pro potřeby zobrazení. Hodnota content podle CSS3 začíná čárkami odděleným seznamem URL adres definujících soubory, kterými se má nahradit daný element. Tento seznam může být samozřejmě prázdný. Adresy jsou prozkoumávány postupně, pokud je daný soubor použitelný (tedy existuje v daném místě a prohlížeč je schopný ho použít), element je nahrazen jeho obsahem. V opačném případě se prohlížeč pokusí použít další soubor ze seznamu.

Za tímto seznamem následuje definice poslední varianty, pokud všechny pokusy o nahrazení elementu selžou (respektive pokud element nemá definován žádný nahrazující soubor, jde o jedinou variantu, jak element zobrazit). Těchto možností je velké množství, nejčastěji bude asi používáno klíčové slovo contents přikazující, aby byl použit obsah elementu ze zdrojového dokumentu. Také půjde například nahradit obsah elementu řetězcem definovaným ve stylovém předpisu.

Možností nahrazování obsahu elementu je skutečně velké množství a v tomto souhrnném článku je nelze dopodrobna popsat. V následujícím příkladu se tedy pokusím ukázat, k čemu jsou tyto nové schopnosti CSS vůbec dobré. Mějme obrázkový nadpis h1. Chceme, aby na úrovni dokumentu byl tento nadpis vyjádřen textově (kvůli vyhledávačům), ale při zobrazení byl nahrazen grafickým logem. Toto lze řešit následujícím způsobem:


<style>
h1
{
  width: 150px; /* šírka loga */
  height: 80px; /* výška loga */
  background-image: url(„logo.gif“);
}
h1 span
{
  display: none;
}
</style>
</head>
<body>
<h1><span>Název organizace</span></h1>

Nadpis má na pozadí obrázek logo.gif a takový rozměr, aby se do něj dané logo vešlo přesně jednou. Textová část nadpisu je uvnitř elementu span, který má zakázané zobrazování. Variace na toto řešení jsou dnes nejelegantnějším způsobem, jak vytvořit grafický nadpis a přitom mít na úrovni dokumentu i příslušný text. Není to však řešení úplně nejčistší, máme zde jeden zbytečný span a navíc nadpis musí mít pomocí vlastností width a height definovánu velikost odpovídající danému souboru s logem – což znamená, že při použití jiného loga musíme ve stylovém předpisu tyto údaje přepsat.

Pomocí nahrazovacích vlastností CSS3 půjde tento problém vyřešit mnohem elegantněji:


<style>
h1
{
  content: url(„logo.gif“), contents;
}
</style>
</head>
<body>
<h1>Název organizace</h1>

Toto řešení plně pokrývá daný problém a oproti předchozímu kódu přináší i něco navíc. Pokud soubor logo.gif existuje, je jím element h1 nahrazen. Nemusíme mu ani nastavovat přesné rozměry, protože se stává nahrazovaným elementem, který automaticky přebírá rozměry své náhrady. V opačném případě je použit obsah elementu, tedy textová reprezentace loga uvedená ve zdrojovém dokumentu. Oproti předchozímu řešení je zde navíc ošetřena i situace, kdy prohlížeč nezpracuje daný grafický soubor.

Přesouváme elementy na jiné místo

V předchozím textu jsme si ukázali, že lze pomocí pseudoelementů definovat nové elementy, které nejsou součástí původního dokumentu. Modul však umožňuje i nahrazovat obsah jednoho elementu jiným, což jinak řečeno znamená přesouvat elementy.

Nová vlastnost move-to značí, že daný element má být přesunut na jiné místo. Identifikátor tohoto místa tvoří hodnotu této vlastnosti. Vzhledem k tomu, že chceme tímto elementem nahradit jiný element, použijeme u cíle známou vlastnost content, konkrétně její hodnotu pending(identifikator).

Speciálně pro přesouvání obsahu byl navržen pseudoelement ::alternate. Ve zkratce jde o to, že často budeme chtít, aby daný element zůstal na svém místě, ale určitá informace o něm byla přenesena na místo jiné. Tento pseudoelement má jediný význam, lze jej naplnit informacemi z elementu, kterému je přiřazen (jeho obsahem, hodnotou některého z atributů) a pak přenést na jiné místo.

V posledním kostrbatém příkladu tohoto článku chtějme na začátku dokumentu zobrazovat kompletní číslovaný seznam URL adres, které jsou používány v celém textu jako odkaz. Tento seznam bude umístěn před element body:

body::before
{
  display: block;
  content: pending(links);
  padding: 10px;
  border: 1px solid black;
  margin-bottom: 10px; /* mezera před tělem dokumentu */
}

Tím jsme si připravili kontejner (pojmenovaný links) pro všechny naše odkazy bez toho, abychom museli zasahovat do samotného XHTML dokumentu. Nyní chceme, aby každý odkaz zvyšoval počítadlo (pojmenované linkNr) o 1 a aby se na jeho konci zobrazilo toto jeho pořadové číslo:

a[href]
{
  counter-increment: linkNr;
}
a[href]::after
{
  content: “ [“ counter(linkNr) „]“;
}

Protože odkaz musí samozřejmě zůstat na svém místě a navíc z něj potřebujeme pouze hodnotu jeho atributu href, vytvoříme pro něj alternativní element, který se bude formátovat jako položka seznamu, přičemž jeho číslo bude odpovídat číslu odkazu uvedenému v dokumentu:

a[href]::alternate
{
  display: list-item;
  content: attr(href); /*atribut href elementu, kterému je přiřazen*/
  move-to: links;
}
a[href]::alternate::marker
{
  content: counter(linkNr);
}

Pseudoelement ::marker slouží k přístupu ke značce položky seznamu. V tomto případě její obsah tvoří počítadlo odkazu.

Těmito několika pravidly jsme dosáhli požadovaného výsledku, a to bez toho, abychom šáhli do zdroje dokumentu! (Omlouvám se za poněkud těžkopádný příklad, ale jen tak lze dokumentovat většinu novinek tohoto modulu v praxi.)

Formátování seznamů

Je více než zřejmé, že pro drtivou většinu uživatelů se budou pojmy generovaný obsah a seznamy víceméně překrývat a dosud popisované novinky pro ně zůstanou španělskou vesnicí. Přestože veškeré chování seznamů, tak jak je známe z XHTML, lze popsat prostředky z výše komentovaného modulu Generated and Replaced Content, ponechalo W3C i modul Lists popisující možnosti formátování seznamů. I tento modul je zatím ve fázi pracovního návrhu.

Modul se nijak neliší od možností z CSS2. Doplňuje několik nových stylů číslování a především upřesňuje jejich algoritmy číslování (například algoritmus číslování pomocí římských číslic), které byly dříve definovány velmi mlhavě nebo vůbec.

Souhrn

Tento článek pouze naznačil velmi rozsáhlé možnosti kaskádových stylů na poli nahrazovaného a generovaného obsahu. Jde o skutečně radikální navýšení schopností CSS, které ovšem musí být používány s citem. Jinak se může stát, že paradigma oddělování formy od obsahu bude postaveno na hlavu tím, že obsah (dokument) začne zasahovat do formy (styl)!

Na druhou stranu nám tyto novinky umožní mnohem jednodušeji dosahovat některých efektů, které mají dnes za následek přidávání dalších zbytečných elementů do zdrojového dokumentu nebo duplikování jeho obsahu, jak bylo demonstrováno na některých příkladech.

Otázka, na kterou odpoví až čas, je úroveň implementace těchto možností v prohlížečích. Jde o poměrně složité operace s obsahem dokumentu, přesto doufejme, že alespoň větší část těchto vlastností najde odezvu i v prohlížečích.

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

Štítky: Články

Mohlo by vás také zajímat

Nejnovější

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *