Cascada i herència

This translation is incomplete. Please help translate this article from English.

En un article anterior, vam entrar en els diversos selectors CSS. En algun moment del vostre treball, us trobareu en la situació en què diverses regles CSS tindran selectors que coincideixin amb el mateix element. En aquests casos, quina regla CSS "guanya", i acaba sent la que finalment s'apliqui a l'element?. Això està controlat per un mecanisme anomenat Cascada; això també està relacionat amb l'herència (els elements portaran alguns valors de propietat dels seus pares, però no d'altres). En aquest article anem a definir què és la cascada, quina especificitat és, quina importància té, i com les propietats hereten de diferents regles.

Requisits previs: Coneixements bàsics d'informàtica, el programari bàsic instal.lat, el coneixement bàsic del treball amb fitxers, els fonaments d'HTML (estudi d'Introducció a HTML), i una idea de com funciona CSS (estudiar els articles anteriors d'aquest mòdul).
Objectiu: Conèixer la cascada i l'especificitat, i com funciona l'herència en CSS.

L'estil final d'un element es pot especificar en molts llocs diferents, que poden interactuar de manera complexa. Aquesta interacció complexa fa que CSS sigui potent, però també pot fer que sigui confús i difícil de depurar. Aquest article pretén aclarir part d'aquesta complexitat. Si no ho enteneu immediatament, no us preocupeu, aquesta és una de les parts més difícils de comprendre la teoria de CSS. Us recomanem que proveu-ho ara, però, a continuació, mantingueu-ho a prop com una guia útil per tornar a fer preguntes sobre la cascada i l'herència.

La cascada

CSS és un acrònim de Cascading Style Sheets, que indica que la noció de la cascada és important. En el seu nivell més bàsic indica que l'ordre de les normes CSS és important, però és més complex que això. El que els selectors guanyen en la cascada depèn de tres factors (aquests es classifiquen per ordre de pes: els anteriors anul·laran els posteriors):

  1. Importància
  2. Especificitat
  3. Ordre de la font

Importància

A CSS hi ha una sintaxi especial que podeu utilitzar per assegurar-vos que una determinada regla sempre guanyarà sobre tots els altres !important. Si afegiu això al final d'un valor de propietat, se li donarà superpoders.

Vegem un exemple:

<p class="better">This is a paragraph.</p>
<p class="better" id="winning">One selector to rule them all!</p>
#winning {
  background-color: red;
  border: 1px solid black;
}

.better {
  background-color: gray;
  border: none !important;
}

p {
  background-color: blue;
  color: white;
  padding: 5px;
}

Això produeix el següent:

Anem a repassar això per veure que és el que està passant.

  1. Veureu que els valors de color i padding de la tercera regla s'han aplicat, però no té el background-color. Per què? Realment, totes tres haurien d'aplicar-se, perquè les regles posteriors en l'ordre de la font en general anul·len les regles anteriors.
  2. No obstant això, les regles anteriors guanyen, perquè els selectors IDs/class tenen una major especificitat que els selectors d'elements (obtindreu més informació sobre això a la següent secció).
  3. Ambdós elements tenen una class better, però la segona té també un id winning. Atès que els IDs tenen una especificitat encara més alta que les class (només es pot tenir un element amb cada ID únic en una pàgina, però molts elements amb la mateixa class - els selectors ID són molt específics en el que apunten), el color de fons vermell i 1 pixel de vora negra s'hauria d'aplicar al segon element, amb el primer element obtenint el color gris i sense vora, tal com especifica la classe.
  4. El segon element obté el color de fons vermell, però no hi ha cap vora. Per què? A causa de la declaració !important en la segona regla - inclosa aquesta després de border: none significa que aquesta declaració guanyarà el valor de la vora de la regla anterior, tot i que l'ID té una especificitat més alta.

Nota: L'única manera d'anul·lar aquesta declaració !important seria incloure una altra declaració !important de la mateixa especificitat, més endavant en l'ordre de la font.

És útil saber que !important existeix perquè sàpigues el que és quan et trobes amb ell en el codi d'altres persones. PERÒ. Us aconsellem que no l'utilitzeu mai tret que sigui absolutament necessari. Una de les situacions en què és possible que l'utilitzeu és quan feu servir un CMS on no podeu editar els mòduls bàsics de CSS, i voleu substituir un estil que no es pugui reemplaçar d'una altra manera. Però, en realitat, no l'utilitzeu si podeu evitar-ho. Perquè: !important canvia la forma en què la cascada normalment funciona, pot fer que els problemes de depuració CSS siguin realment difícils de treballar, sobretot en una gran fulla d'estil.

També és útil tenir en compte que la importància d'una declaració CSS depèn del full d'estil en què s'especifiqui: és possible que els usuaris estableixin fulls d'estil personalitzats per substituir els estils del desenvolupador, per exemple, l'usuari pot ser un discapacitat visual i voleu configurar la mida de la font a totes les pàgines web que visiten perque sigui el doble de la mida normal per facilitar-ne la lectura.

Les declaracions contradictòries s'aplicaran en el següent ordre, amb les posteriors que anul·lin les anteriors:

  1. Declaracions dels fulls d'estil de l'agent d'usuari (p. ex., els estils predeterminats del navegador, s'utilitzen quan no s'estableix cap altre estil).
  2. Declaracions normals en fulls d'estil d'usuari (estils personalitzats establerts per un usuari).
  3. Declaracions normals en fulls d'estil d'autor (aquests són els estils establerts per nosaltres, els desenvolupadors web).
  4. Declaracions importants en fulls d'estil d'autor
  5. Declaracions importants en fulls d'estil d'usuari

Té sentit que els fulls d'estils dels desenvolupadors web anul·lin els fulls d'estils dels usuaris, de manera que el disseny es pogui conservar tal com es vol, però de vegades els usuaris tenen bones raons per substituir els estils dels desenvolupadors web, com es va esmentar anteriorment, es pot aconseguir usant !Important en les seves regles.

Especificitat

Especificitat és, bàsicament, una mesura de com és d'específic un selector: quants elements podrien coincidir. Com es pot veure a l'exemple anterior, els selectors d'elements tenen una especificitat baixa. Els selectors de classe (class) tenen una especificitat més alta, de manera que guanyaran contra els selectors d'elements. Els selectors ID tenen una especificitat encara més gran, de manera que guanyaan contra els selectors de classe (class). L'única manera de guanyar contra un selector ID és utilitzar !important.

La quantitat d'especificitat que té un selector es mesura usant quatre valors diferents (o components), que poden ser considerats com milers, centenes, desenes i uns - quatre dígits individuals en quatre columnes:

  1. Milers: marqueu u en aquesta columna si el selector coincident és dins d'un element <style> o la declaració és dins d'un atribut style (aquestes declaracions no tenen selectors, de manera que la seva especificitat sempre és simplement 1000.) En cas contrari 0.
  2. Centenars: marqueu u en aquesta columna per cada selector ID que es troba dins del selector general.
  3. Desenes: marqueu u en aquesta columna per a cada selector de classe (class), selector d'atributs o pseudo-class contingut dins del selector general.
  4. Unitats: marqueu u en aquesta columna per a cada selector d'elements o pseudo-element que es troba dins del selector general.

Nota: Selector universal (*), combinators (+, >, ~, ' ') i negació pseudo-class (:not) no tenen cap efecte en l'especificitat.

La taula següent mostra alguns exemples aïllats perquè t'animis. Intenta passar per aquests i assegurar-te d'entendre per què tenen l'especificitat que els hem donat.

Selector Milers Centenars Desenes Unitats Total especificitat
h1 0 0 0 1 0001
#important 0 1 0 0 0100
h1 + p::first-letter 0 0 0 3 0003
li > a[href=*"en-US"] > .inline-warning 0 0 2 2 0022
#important div > div > a:hover, inside a <style> element 1 1 1 3 1113

Nota: Si diversos selectors tenen la mateixa importància i especificitat, el selector que guanya ve decidit pel que ve més endavant en el Source order.

Abans de continuar, vegem un exemple en acció. Aquest és el codi HTML que anem a utilitzar:

<div id="outer" class="container">
  <div id="inner" class="container">
    <ul>
      <li class="nav"><a href="#">One</a></li>
      <li class="nav"><a href="#">Two</a></li>
    </ul>
  </div>
</div>

I aquí teniu el CSS per a l'exemple:

/* specificity: 0101 */
#outer a {
  background-color: red;
}

/* specificity: 0201 */
#outer #inner a {
  background-color: blue;
}

/* specificity: 0104 */
#outer div ul li a {
  color: yellow;
}

/* specificity: 0113 */
#outer div ul .nav a {
  color: white;
}

/* specificity: 0024 */
div div li:nth-child(2) a:hover {
  border: 10px solid black;
}

/* specificity: 0023 */
div li:nth-child(2) a:hover {
  border: 10px dashed black;
}

/* specificity: 0033 */
div div .nav:nth-child(2) a:hover {
  border: 10px double black;
}

a {
  display: inline-block;
  line-height: 40px;
  font-size: 20px;
  text-decoration: none;
  text-align: center;
  width: 200px;
  margin-bottom: 10px;
}

ul {
  padding: 0;
}

li {
  list-style-type: none;
}

El resultat que obtenim d'aquest codi és el següent:

Llavors, què està passant aquí? En primer lloc, només estem interessats en les set primeres regles d'aquest exemple, i com notaràs, hem inclòs els seus valors d'especificitat en un comentari abans de cadascun.

  • Els dos primers selectors estan competint per l'estil del color de fons de l'enllaç: el segon guanya i fa que el color de fons sigui blau perquè té un selector ID addicional a la cadena: la seva especificitat és 201 versus 101.
  • El tercer i el quart selectors competeixen per l'estil del color de text de l'enllaç; el segon guanya i fa que el text sigui blanc perquè, encara que té un selector d'elements que és menor, el selector que falta és canviat per a un selector de classe, que val deu més que u. Així, l'especificitat guanyadora és 113 versus 104.
  • Els selector 5-7 estan competint sobre l'estil de la vora de l'enllaç quan s'hi desplacen. El selector sis perd clarament a cinc amb una especificitat de 23 versus 24: té un menor nombre de selectors en la cadena. El selector set, no obstant aixó, supera tant el cinc com el sis: té el mateix nombre de subselectors en la cadena que el cinc, però s'ha canviat un element per a un selector de classes. Així, l'especificitat guanyadora és 33 versus 23 i 24.

Nota: si encara no ho heu fet, reviseu tots els selectors una vegada més, només per assegurar-vos d'entendre per què els valors d'especificitat s'han concedit com es mostra.

Ordre de la font

Com s'ha comentat anteriorment, si diversos selectors competidors tenen la mateixa importància i especificitat, el tercer factor que entra en joc per ajudar a decidir quina regla guanya és l'ordre de la font, les regles posteriors guanyaran a les regles anteriors. Per exemple:

p {
  color: blue;
}

/* This rule will win over the first one */
p {
  color: red;
}

Mentre que en aquest exemple la primera regla guanya perquè l'ordre de la font és anul·lat per l'especificitat:

/* This rule will win */
.footnote {
  color: blue;
}

p {
  color: red;
}

Una nota sobre la barreja de regles

Una cosa que cal tenir en compte en considerar tota aquesta teoria en cascada, i quins estils aconseguir aplicar sobre altres estils, és que tot això succeeix a nivell de propietat : les propietats anul·len altres propietats, però no tenim regles senceres que anul·lin altres regles. Quan diverses regles CSS coincideixen amb el mateix element, totes s'apliquen a aquest element. Només després d'això, es valoraran les propietats conflictives per veure quins estils individuals guanyaran sobre els altres.

Vegem un exemple. Primer, algun HTML:

<p>I'm <strong>important</strong></p>

I ara algun CSS que l'estilem amb:

/* specificity: 0002 */
p strong {
  background-color: khaki;
  color: green;
}

/* specificity: 0001 */
strong {
  text-decoration: underline;
  color: red;
}

Resultat:

En aquest exemple, a causa de la seva especificitat, la propietat color de la primera regla invalida la propietat de color de la segona regla. No obstant això, tant background-color de la primera regla com la text-decoration de la segona regla s'apliquen a l'element <strong>. També notareu que el text d'aquest element està en negreta: això prové del full d'estils per defecte dels navegadors.

Herència

L'herència CSS és l'última peça que necessitem investigar per obtenir tota la informació i entendre quin estil s'aplica a un element. La idea és que alguns dels valors de propietat aplicats a un element seran heretats pels fills d'aquest element, i alguns no ho faran.

  • Per exemple, té sentit que font-family i color es puguin heretar, ja que això facilita la configuració d'un tipus de lletra base per tot el lloc aplicant una familia de fonts a l'element <html>; Podeu sobreescriure les fonts en elements individuals quan sigui necessari. Seria realment molest haver d'establir la font base per separat a cada element.
  • Un altre exemple, té sentit per a margin, padding, border, i background-image que NO s'heretin. Imagineu l'embolic d'estil/diseny que es produiria si s'establissin aquestes propietats en un element contenidor i s'heretessin per a cada element fill únic i després haver de canviar-los en cada element individual!

Quines propietats són heretades de manera predeterminada i quines no es deu en gran mesura al sentit comú. Tanmateix, si voleu estar segurs, podeu consultar la CSS Referencia - cada pàgina de propietats separada s'inicia amb una taula resum, que inclou diversos detalls sobre aquest element, incloent-hi si s'hereta o no.

Control de l'herència

CSS proporciona tres valors especials per gestionar l'herència:

  • inherit : Aquest valor estableix que el valor de la propietat aplicat a un element seleccionat sigui el mateix que el del seu element pare.
  • initial : Aquest valor estableix que el valor de propietat aplicat a un element seleccionat sigui el mateix que el valor establert per a aquest element en la fulla d'estils predeterminada del navegador. Si el full d'estils predeterminat del navegador no estableix cap valor i la propietat s'hereta de forma natural, el valor de la propietat s'estableix en herència (inherit).
  • unset : Aquest valor restaura la propietat al seu valor natural, el que significa que si la propietat està heretada naturalment actua com a herència (inherit), en cas contrari actua com a inicial (initial).

El valor inherit és el més interessant: ens permet fer, explícitament, que un element hereti un valor de propietat dels seus pares.

Vegem un exemple. Primer algun HTML:

<ul>
  <li>Default <a href="#">link</a> color</li>
  <li class="inherit">Inherit the <a href="#">link</a> color</li>
  <li class="initial">Reset the <a href="#">link</a> color</li>
  <li class="unset">Unset the <a href="#">link</a> color</li>
</ul>

I ara algun CSS que l'estilem amb:

body {
  color: green;
}

.inherit a {
  color: inherit;
}

.initial a {
  color: initial
}

.unset a {
  color: unset;
}

Resultat:

Expliquem el que està passant aquí:

  • Primer hem establert color del <body> en verd.
  • Com la propietat color és heretada naturalment, tots els elements fills del cos tindran el mateix color verd. Cal assenyalar que els navegadors estableixen el color dels enllaços a blau per defecte en lloc de permetre l'herència natural de la propietat color, de manera que el primer enllaç de la nostra llista és blau.
  • La segona regla estableix vincles dins d'un element amb la classe inherit per heretar el seu color des del seu pare. En aquest cas, vol dir que l'enllaç hereta el seu color del seu pare <li>, que, per defecte hereta el seu color del seu propi pare <ul>, que en última instància hereta el seu color a partir de l'element <body>, que tenia el seu color establert en verd (green) per la primera regla.
  • La tercera regla selecciona els enllaços d'un element amb la classe initial i estableix el seu color a initial. Normalment, el valor initial establert pels navegadors per al color del text és negre, de manera que aquest enllaç està en negre.
  • L'última regla selecciona tots els enllaços dins d'un element amb la classe unset i estableix el seu color a unset - descartem el valor. Com que la propietat del color és una propietat heretada naturalment, actua exactament com establir el valor a inherit. Com a conseqüència, aquest enllaç s'estableix en el mateix color que el cos - verd.

Aprenentatge actiu: jugar amb la cascada

En aquest aprenentatge actiu, ens agradaria que experimentéssiu escrivint una única nova regla que substituís el color i el color de fons que hem aplicat als enllaços per defecte. Podeu utilitzar un dels valors especials que hem vist a la secció Controlling_inheritance per escriure una declaració en una nova regla que restableixi el color de fons de nou a blanc, sense utilitzar un valor de color real?

Si cometeu un error, sempre podeu restablir-lo mitjançant el botó Reset. Si esteu realment atrapats, premeu el botó Show solution per veure una resposta potencial.

Que segueix

Si heu entès la major part d'aquest article, ja està bé, ja heu començat a familiaritzar-vos amb la mecànica fonamental de CSS. L'última part de la teoria central és el model de caixa, que veurem a continuació.

Si no enteneu completament la cascada, l'especificitat i l'herència, no us preocupeu!. Definitivament, això és el més complicat que hem cobert fins ara en el curs, i és alguna cosa, que fins i tot els desenvolupadors web professionals de vegades ho troben difícil. Recomanem que torneu a aquest article diverses vegades a mesura que continueu el curs i seguiu pensant en això. Torneu a consultar aquí si comenceu a tenir problemes estranys amb els estils que no s'apliquen com s'esperava. Pot ser un problema d'especificitat.

Document Tags and Contributors

 Contributors to this page: Legioinvicta
 Last updated by: Legioinvicta,