Estil

  • Un selector ens permet seleccionar de manera declarativa un subconjunt d'elements de la nostra pàgina

    Introducció

    Un document .css és un conjunt de selectors formats per un conjunt de regles que apliquen uns estils determinats als elements seleccionats.

    Entorn de treball

    Instal·la Deno.

    Terminal window
    irm https://deno.land/install.ps1 | iex

    Clona el projecte https://gitlab.com/xtec/web/document-style amb Git:

    Terminal window
    git clone https://gitlab.com/xtec/web/document-style.git
    cd document-style
    rm -r -force .git
    deno install --allow-scripts

    A continuació arrenca el client de Tailwind

    deno run dev

    L’script arrenca tailwind en mode “watch”, de manera que cada cop que modifiquis el fitxer main.css, tailwind torna a generar el fitxer public/main.css.

    ≈ tailwindcss v4.1.14
    Done in 101ms
    Done in 143µs
    Done in 974µs

    Tailwind

    Obre el projecte amb WebStorm (o PyCharm).

    Obre el document page/index.html amb el navegador:

    El client de tailwind genera el fitxer public/main.css a partir del fitxer main.css.

    Si et fixes en el <head> del document HTML public/index.html, pots veure que té un <link> de tipus stylesheet a l’URL ./main.css.

    El navegador, en carregar el document web, segueix l’enllaç i processa la fulla d’estil.

    Tailwind només afegeix les classes utilitzades als documents HTML, creant el CSS més petit possible!

    Selector

    Quan un navegador carrega un document HTML, converteix aquest document en un mòdel d’objectes: DOM (Document Object Module).

    Un DOM representa el document en memòria com un arbre de nodes, o arbre DOM, on cada node representa un part del document.

    Els selectors són expressions que, igual que fas amb una base de dades, et permet crear una consulta que et tornarà un conjunt de nodes que compleixen els criteris del selector.

    Modifica el fitxer public/index.html:

    public/index.html
    <h1 class="text-2xl font-bold m-4">La precària i habitual poesia</h1>
    <div>La poesia té una cosa empipadora</div>
    <div>és la rima, la musiqueta,</div>
    <div>la música externa,</div>
    <div>la persistent, pesada musiqueta.</div>

    Per aplicar les mateixes classes a tots els elements <div> de la llista, has de repetir les mateixes classes per cada element <div>:

    index.html
    <!DOCTYPE html>
    <html lang="ca">
    <head>
    <title>La precària i habitual poesia</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.tailwindcss.com?plugins=typography"></script>
    </head>
    <body class="prose">
    <h1 class="text-2xl font-bold m-4">La precària i habitual poesia</h1>
    <div class="ms-4 font-semibold text-lg text-gray-500">La poesia té una cosa empipadora</div>
    <div class="ms-4 font-semibold text-lg text-gray-500">és la rima, la musiqueta,</div>
    <div class="ms-4 font-semibold text-lg text-gray-500">la música externa,</div>
    <div class="ms-4 font-semibold text-lg text-gray-500">la persistent, pesada musiqueta.</div>
    </body>
    </html>

    La precària i habitual poesia

    La poesia té una cosa empipadora
    és la rima, la musiqueta,
    la música externa,
    la persistent, pesada musiqueta.

    Si vols, en lloc de repetir les mateixes classes per cada element <div>, pots utilitzar un selector CSS per aplicar a tots els elements <div> la mateixa classe.

    index.html
    <!DOCTYPE html>
    <html lang="ca">
    <head>
    <title>La precària i habitual poesia</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.tailwindcss.com?plugins=typography"></script>
    <style type="text/tailwindcss">
    @layer base {
    div {
    @apply ms-4 font-semibold text-lg text-gray-500;
    }
    }
    </style>
    </head>
    <body>
    </body>
    </html>
    Nota

    El selector CSS només funcional si els elements no estan dins d’un context prose. 😾

    En una activitat posterior ja aprendras com pots modificar el plugin Tailwind - Typography.

    Regla

    Un regla CSS es pot declarar dins de l’element <head> d’un document amb el bloc <style>:

    index.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <title>Selector</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.tailwindcss.com?plugins=typography"></script>
    <style type="text/tailwindcss">
    @layer base {
    h1 {
    @apply text-red-500 text-2xl
    }
    }
    </style>
    </head>
    <body>
    <h1>I'm red!</h1>
    </body>
    </html>

    I’m red!

    La regla comença amb un selector, que selecciona tots els elements <h1>:

    h1 {
    @apply text-red-500 text-2xl
    }

    Dins de { } tens dos utility classes: text-red-500 i text-2xl.

    Pots declarar tantes regles com vulguis dins d’un bloc <style>:

    index.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <title>Selector</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.tailwindcss.com?plugins=typography"></script>
    <style type="text/tailwindcss">
    @layer base {
    h1 {
    @apply text-red-500 text-2xl
    }
    p {
    @apply text-green-700
    }
    }
    </style>
    </head>
    <body>
    <h1>I'm red!</h1>
    <p>I'm green :-)</p>
    <p>It's nice</p>
    </body>
    </html>

    I’m red!

    I’m green :-)

    It’s nice

    En aquest cas tenim dos regles: una pels elements <h1>, una altra pels elements <p>:

    h1 {
    @apply text-red-500 text-2xl
    }
    p {
    @apply text-green-700
    }

    Element

    A continuació veurem diferents exemples de regles a partir d’aquest document HTML:

    index.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <title>Selector</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.tailwindcss.com?plugins=typography"></script>
    <style type="text/tailwindcss">
    @layer base {
    h1 {
    @apply text-red-500 text-2xl
    }
    p {
    @apply text-green-700
    }
    }
    </style>
    </head>
    <body>
    <h1>I am a level one heading</h1>
    <p>This is a paragraph of text. In the text is a <span>span element</span>
    and also a <a href="https://google.com">link</a>.</p>
    <p>This is the second paragraph. It contains an <em>emphasized</em> element.</p>
    <ul>
    <li>Item <span>one</span></li>
    <li>Item two</li>
    <li>Item <em>three</em></li>
    </ul>
    </body>
    </html>

    Amb aquestes regles el document es veu així:

    I am a level one heading

    This is a paragraph of text. In the text is a span element and also a link.

    This is the second paragraph. It contains an emphasized element.

    • Item one
    • Item two
    • Item three

    Pots fer servir diversos selectors al mateix temps separant-los amb una coma:

    h1 {
    @apply text-red-500 text-2xl
    }
    p, li {
    @apply text-green-700
    }

    Pots veure que el selector s’aplica a tots els elements <p> i <li>:

    I am a level one heading

    This is a paragraph of text. In the text is a span element and also a link.

    This is the second paragraph. It contains an emphasized element.

    • Item one
    • Item two
    • Item three
    Activitat

    Afegeix una regla que selecciona els elements li i els sagna a la dreta:

    Afegeix una regla que selecciona els elements p i aplica un marge a dalt i abaix:

    El resultat ha de ser semblant a aquest:

    I am a level one heading

    This is a paragraph of text. In the text is a span element and also a link.

    This is the second paragraph. It contains an emphasized element.

    • Item one
    • Item two
    • Item three

    Classe

    Pots seleccionar elements a partir dels valors de l’atribut class.

    Modifica el segon element de la llista, afegint una atribut class:

    <ul>
    <li>Item one</li>
    <li class="special">Item two</li>
    <li>Item <em>three</em></li>
    </ul>

    Per indicar que el selector és d’un valor de l’atribut classe, has de posar un punt a l’inici del selector.

    Afegeix aquesta regla al final de l’element <style>:

    .special {
    @apply text-orange-500 font-bold
    }

    Pots veure que aquesta regla només s’aplica al segon element de la llista:

    I am a level one heading

    This is a paragraph of text. In the text is a span element and also a link.

    This is the second paragraph. It contains an emphasized element.

    • Item one
    • Item two
    • Item three

    Les regles s’apliquen de dalt a baix (en cascada), i una regla que s’aplica després sobreescriu una que s’ha aplicat abans.

    h1 {
    @apply text-red-500 text-2xl
    }
    p, li {
    @apply text-green-700
    }
    p {
    @apply my-2
    }
    li {
    @apply ml-6 list-disc
    }
    .special {
    @apply text-orange-500 font-bold
    }

    Pots aplicar la classe special a qualsevol element del document que vulguis que tingui el mateix aspecte que el segon element de la llista:

    index.html
    <body>
    <h1>I am a level one heading</h1>
    <p>This is a paragraph of text. In the text is a <span class="special">span element</span>
    and also a <a href="https://google.com">link</a>.</p>
    <p>This is the second paragraph. It contains an <em>emphasized</em> element.</p>
    <ul>
    <li>Item <span>one</span></li>
    <li class="special">Item two</li>
    <li>Item <em>three</em></li>
    </ul>
    </body>

    I am a level one heading

    This is a paragraph of text. In the text is a span element and also a link.

    This is the second paragraph. It contains an emphasized element.

    • Item one
    • Item two
    • Item three

    Si vols ser més precís, pots seleccionar per element i classe a la vegada:

    li.special {
    @apply text-orange-500 font-bold
    }

    Aquesta regla només s’aplica als elements <li> que tenen un valor de classe special:

    <li class="special">

    Per tant, aquesta regla CSS ja no s’aplica a l’element <span> encara que tingui l’atribut class amb el valor special perquè no és un element <li>:

    I am a level one heading

    This is a paragraph of text. In the text is a span element and also a link.

    This is the second paragraph. It contains an emphasized element.

    • Item one
    • Item two
    • Item three

    Ubicació

    Un document HTML s’estructuren en forma d’arbre invertit:

    html

    head

    body

    h1

    p

    p

    p

    em

    ul

    li

    li

    li

    em

    En el nostre document hi ha dos elements <em>.

    Pots seleccionar un element <em> en funció de la seva ubicació respecte a un altre element.

    Per exemple, aquesta regla només s’aplica a aquells elements <em> que són descendents d’un element <li>:

    li em {
    @apply text-purple-800
    }

    Pots veure que ara el <em> del tercer element <li> és de color porpra, però el que hi ha dins de la <p> no s’ha modificat:

    I am a level one heading

    This is a paragraph of text. In the text is a span element and also a link.

    This is the second paragraph. It contains an emphasized element.

    • Item one
    • Item two
    • Item three

    També pots seleccionar un element que està a continuació de l’altre:

    Per exemple, aquesta regla selecciona totes les <p>s que estan a continuació d’un <h1>:

    h1 + p {
    @apply text-xl;
    }

    I am a level one heading

    This is a paragraph of text. In the text is a span element and also a link.

    This is the second paragraph. It contains an emphasized element.

    • Item one
    • Item two
    • Item three
    Activitat

    Prova d’afegir una regla per fer que un span sigui vermell si es troba dins d’un paràgraf.

    I am a level one heading

    This is a paragraph of text. In the text is a span element and also a link.

    This is the second paragraph. It contains an emphasized element.

    • Item one
    • Item two
    • Item three

    Val la pena assenyalar que pots combinar diversos selectors i combinadors junts.

    Per exemple:

    /* selecciona qualsevol <span> que estigui dins d'un <p>, que estigui dins d'un <article> */
    article p span {
    }
    /* selecciona qualsevol <p> que ve directament després d'un <ul>, que ve directament després d'un <h1> */
    h1 + ul + p {
    }

    També podeu combinar diversos tipus junts.

    Prova d’afegir el següent al teu codi:

    body h1 + p .special {
    @apply text-yellow-400 bg-black p-1;
    }

    Això dona estil a qualsevol element amb una classe <special>, que es troba dins d’un <p>, que ve just després d’un <h1>, que es troba dins d’un <body>. Uf! 😵‍💫

    No et preocupis si això sembla complicat en aquest moment: aviat començaràs a entendre-ho a mesura que escrius més CSS.

    I am a level one heading

    This is a paragraph of text. In the text is a span element and also a link.

    This is the second paragraph. It contains an emphasized element.

    • Item one
    • Item two
    • Item three

    Estat

    També pots afegir estils en funció de l’estat d’un element.

    Un exemple senzill d’això és quan s’estilen els enllaços <a>.

    Aquest té diferents estats segons si no és visitat, visitat, passant el cursor per sobre, enfocat mitjançant el teclat o en procés de fer clic (activar).

    Pots afegir una regla per tal que els enllaços siguin de color blau amb subratllat, i que la lletra es torni més forta quan el cursor estigui a sobre d’ells.

    a:link {
    @apply text-blue-500 underline;
    }
    a:hover {
    @apply font-bold;
    }

    I am a level one heading

    This is a paragraph of text. In the text is a span element and also a link.

    This is the second paragraph. It contains an emphasized element.

    • Item one
    • Item two
    • Item three

    Comentaris

    Com amb qualsevol treball de codificació, és una bona pràctica escriure comentaris juntament amb el CSS. Això t’ajuda a recordar com funciona el codi quan hi tornes més tard per fer correccions o millores. També ajuda els altres a entendre el codi.

    Els comentaris CSS comencen amb /* i acaben amb */.

    A l’exemple següent, els comentaris marquen l’inici de seccions diferents del codi. Això ajuda a navegar per la base de codi a mesura que es fa més gran. Amb aquest tipus de comentaris, cercar comentaris al teu editor de codi es converteix en una manera eficient de trobar una secció de codi.

    /* ... */

    Render

    Quan un navegador mostra un document, ha de combinar el contingut del document amb la seva informació d’estil.

    Processa el document en diverses etapes, que hem llistat a continuació. Tingues en compte que aquesta és una versió molt simplificada del que passa quan un navegador carrega una pàgina web, i que diferents navegadors gestionaran el procés de maneres diferents. Però això és aproximadament el que passa.

    1. El navegador carrega l’HTML (per exemple, el rep de la xarxa).

    2. Converteix l’HTML en un DOM (Document Object Model). El DOM representa el document a la memòria de l’ordinador. El DOM s’explica amb una mica més de detall a la següent secció.

    3. El navegador després recupera la majoria dels recursos que estan enllaçats pel document HTML, com ara imatges incrustades, vídeos i fins i tot CSS enllaçat! JavaScript es gestiona una mica més tard en el procés, i no en parlarem aquí per mantenir les coses més simples.

    4. El navegador analitza el CSS recuperat i ordena les diferents regles pels seus tipus de selector en diferents “cubells”, per exemple, element, classe, ID, etc. Basant-se en els selectors que troba, determina quines regles s’han d’aplicar a quins nodes del DOM, i hi adjunta l’estil segons calgui (aquest pas intermedi s’anomena arbre de renderització).

    5. L’arbre de renderització es distribueix en l’estructura en què hauria d’aparèixer després que les regles s’hi hagin aplicat.

    6. La visualització visual de la pàgina es mostra a la pantalla (aquesta etapa s’anomena pintat).

    El diagrama següent també ofereix una visió simple del procés.

    Atach style to DOM nodes

    Load HTML

    Parse HTML

    Crete DOM tree

    Display

    Load CSS

    Parse CSS

    DOM

    Un DOM té una estructura en forma d’arbre. Cada element, atribut i fragment de text del llenguatge de marques es converteix en un node DOM a l’estructura d’arbre. Els nodes es defineixen per la seva relació amb altres nodes DOM. Alguns elements són pares de nodes fills, i els nodes fills tenen germans.

    Entendre el DOM t’ajuda a dissenyar, depurar i mantenir el teu CSS perquè el DOM és on el teu CSS i el contingut del document es troben. Quan comencis a treballar amb les DevTools del navegador, estaràs navegant pel DOM mentre selecciones elements per veure quines regles s’apliquen.

    Una representació DOM real

    En lloc d’una explicació llarga i avorrida, vegem un exemple per veure com un fragment HTML real es converteix en un DOM.

    Prenem el següent codi HTML:

    <p>
    Let's use:
    <span>Cascading</span>
    <span>Style</span>
    <span>Sheets</span>
    </p>

    Al DOM, el node corresponent al nostre element <p> és un pare. Els seus fills són un node de text i els tres nodes corresponents als nostres elements <span>. Els nodes SPAN també són pares, amb nodes de text com a fills:

    P
    ├─ "Let's use:"
    ├─ SPAN
    | └─ "Cascading"
    ├─ SPAN
    | └─ "Style"
    └─ SPAN
    └─ "Sheets"

    Així és com un navegador interpreta el fragment HTML anterior: renderitza l’arbre DOM anterior i després el mostra al navegador així:

    Let’s use: Cascading Style Sheets

    Aplicar CSS al DOM

    Suposem que afegim una mica de CSS al nostre document per estilitzar-lo.

    De nou, l’HTML és el següent:

    <p>
    Let's use:
    <span>Cascading</span>
    <span>Style</span>
    <span>Sheets</span>
    </p>

    Suposem que hi apliquem el següent CSS:

    span {
    @apply border-1 bg-green-200
    }

    El navegador analitza l’HTML i crea un DOM a partir d’aquest. A continuació, analitza el CSS. Com que l’única regla disponible al CSS té un selector span, el navegador ordena el CSS molt ràpidament! Aplica aquesta regla a cadascun dels tres <span>s i després pinta la representació visual final a la pantalla.

    La sortida actualitzada és la següent:

    Let’s use: Cascading Style Sheets

    Activitat

    Activitat
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    Activitat
    <div>
    <div></div><div></div>
    </div>
    <div>
    <div></div><div></div>
    </div>
    Personatges de Còmic 🎨
    PersonatgeCòmic/SèrieCreadorAny de CreacióCaracterístiques
    Charlie BrownPeanutsCharles M. Schulz1950Pessimista, bon amic, fan del beisbol
    CalvinCalvin and HobbesBill Watterson1985Imaginatiu, traviès, amic d’un tigre
    AstèrixAstèrixRené Goscinny i Albert Uderzo1959Gal valent, fort per la poció màgica
    TintínLes aventures de TintínHergé1929Periodista aventurer, amic de Milú
    Dennis the MenaceDennis the MenaceHank Ketcham1951Nen traviès, sempre en problemes
    MafaldaMafaldaQuino1964Intel·ligent, preocupada pel món
    ZipiZipi y ZapeJosep Escobar1948Bessons traviesos i divertits
    Lucky LukeLucky LukeMorris1946Cowboy ràpid, justicier del Far West
    GarfieldGarfieldJim Davis1978Gat mandrós, amant de la lasanya
    Mortadel·loMortadel·lo i FilemóFrancisco Ibáñez1958Detectius despistats i divertits
    Typography

    Crea una conjunt de regles per estilitzar contingut textual semblant a com ho fa el plugin Tailwind - Typography.

    Pendent

    Google docs