3. modul · CSS alapok · 15. lecke
„Beírtam a szabályt, és mégsem az történik!" — ennek a mondatnak a kilencven százaléka erre a leckére vezethető vissza. Megtanulod, mi dönti el, melyik szabály nyer, ha több is vonatkozik ugyanarra az elemre. Ha ezt megérted, a CSS többé nem fog „önfejűnek" tűnni.
!important kulcsszót és az azonosítókat.
Egy valódi stíluslapban gyakran több szabály is vonatkozik ugyanarra az elemre.
Egy bekezdésre hathat egy p szabály, egy .bevezeto
szabály és egy .kartya p szabály is. Ha ezek ugyanazt a tulajdonságot
állítják be különböző értékre, a böngészőnek döntenie kell.
<p>Milyen színű lettem?</p>
p {
color: blue;
}
p {
color: crimson;
}
Ez eddig egyszerű. De mi van akkor, ha a két kijelölő nem egyforma? Erről szól a lecke többi része.
Fontos tisztázni: a böngésző nem egész szabályok között választ, hanem tulajdonságonként. Ha két szabály különböző tulajdonságokat állít be, akkor nincs ütközés — mindkettő érvényesül.
<p class="kiemelt"> Figyeld meg, honnan jön a stílusom! </p>
p {
color: blue;
font-size: 20px;
font-style: italic;
}
.kiemelt {
color: crimson;
background-color: #fef3c7;
padding: 8px;
}
p szabályból),
sárga hátterű és kitöltött (a .kiemelt szabályból).
Egyedül a color tulajdonság ütközött — azt a
.kiemelt nyerte. Hogy miért, az az 5. pontban derül ki.
A böngésző minden elemnek minden tulajdonságára külön versenyt rendez. A
color tulajdonságért versenyezhet három szabály, a
padding tulajdonságért meg csak egy — az utóbbi tehát automatikusan nyer.
A kaszkád (vízesés, lépcsőzetesség) az a szabályrendszer, ami eldönti, ki nyer egy ütközésnél. A böngésző sorban megy végig ezeken a kérdéseken, és az első olyan lépésnél megáll, ahol eldől a verseny.
Egy erősebb kijelölő mindig nyer, akármilyen korán szerepel a fájlban. A sorrend csak döntetlen esetén számít. Ezt a kezdők gyakran fordítva gondolják: azt hiszik, hogy „ami alul van, az nyer" — pedig ez csak egyforma erős szabályokra igaz.
Kezdjük a legegyszerűbbel, a harmadik lépéssel. Ha két szabály egyforma erős, a később szereplő nyer. „Később" alatt nemcsak a fájlon belüli sorrendet értjük:
| Helyzet | Mi számít „későbbinek"? |
|---|---|
| Egy fájlon belül | Ami lejjebb van a fájlban |
Több <link> a head-ben | Ami később van becsatolva |
<link> és <style> együtt | Amelyik később áll a head-ben |
<button class="gomb">Mentés</button> <button class="gomb">Mégse</button>
/* ===== ALAPBEÁLLÍTÁS ===== */
.gomb {
background-color: #6b7280;
color: white;
border: none;
padding: 8px 16px;
border-radius: 6px;
}
/* ===== KÉSŐBBI MÓDOSÍTÁS ===== */
.gomb {
background-color: #be123c;
}
.gomb szabály felülírta a
háttérszínt, de az összes többi beállítás (fehér szöveg, kitöltés, lekerekítés) megmaradt az
elsőből.
A bevett felépítés: legfelül az általános szabályok (body,
h1, p, a),
alattuk a komponensek (.kartya,
.gomb), és legalul a kivételek, változatok. Így a
sorrend magától a kívánt irányba dolgozik.
A specificitás azt méri, mennyire pontosan céloz egy kijelölő. A logika hétköznapi: minél konkrétabban nevezel meg valamit, annál inkább rád kell hallgatni. „Minden bekezdés" gyengébb utasítás, mint „a kiemelt osztályú bekezdések", és az is gyengébb, mint „pontosan az a bekezdés, amelyiknek ez az azonosítója".
A böngésző minden kijelölőt három számmal jellemez. Megszámolja, hány darab található benne az egyes fajtákból:
| Oszlop | Mi számít bele? |
|---|---|
| 1. azonosítók | #fejlec |
| 2. osztályok és társaik | osztályok (.kartya), attribútum-kijelölők ([type="email"]), pszeudo-osztályok (:hover, :nth-child()) |
| 3. elemek | elemnevek (p, div), pszeudo-elemek (::before) |
| Semmi | a *, a kombinátorok (szóköz, >, +, ~), a vessző |
Balról jobbra, oszloponként — pontosan úgy, ahogy egy sportversenyen az aranyérmek számítanak először, és az ezüstöket csak akkor nézik, ha aranyból egyforma a mérleg.
A 0 – 0 – 11 nem „11", ami nagyobb lenne, mint a 0 – 1 – 0 „10"-e. Egyetlen osztály legyőz akármennyi elemet, és egyetlen azonosító legyőz akármennyi osztályt. A magasabb oszlop mindig mindent visz.
<div> <p class="kiemelt">Milyen színű lettem?</p> </div>
/* 0 – 1 – 0 */
.kiemelt {
color: crimson;
}
/* 0 – 0 – 2 */
div p {
color: blue;
}
div p ugyan később
szerepel és két elemből áll, de a .kiemelt a
második oszlopban vezet — ott eldőlt a verseny, a sorrendet a böngésző meg sem nézte.
<p id="bevezeto" class="szoveg"> Három szabály versenyez értem. </p>
/* 1 – 0 – 0 */
#bevezeto {
color: crimson;
}
/* 0 – 1 – 1 */
p.szoveg {
color: green;
}
/* 0 – 0 – 1 */
p {
color: blue;
}
#bevezeto
szabályt, zöld lenne (0 – 1 – 1 a 0 – 0 – 1 ellen).
Gyakorolj! Takard le a jobb oldali oszlopot, és számold ki magad a specificitást.
| Kijelölő | Specificitás | Miért? |
|---|---|---|
* | 0 – 0 – 0 | A csillag nem számít. |
p | 0 – 0 – 1 | Egy elem. |
ul li | 0 – 0 – 2 | Két elem; a szóköz nem számít. |
ul > li + li | 0 – 0 – 3 | Három elem; a > és a + nem számít. |
.gomb | 0 – 1 – 0 | Egy osztály. |
a:hover | 0 – 1 – 1 | A pszeudo-osztály az osztályok oszlopába tartozik. |
input[type="email"] | 0 – 1 – 1 | Az attribútum-kijelölő is osztály-erejű. |
.kartya p | 0 – 1 – 1 | Egy osztály, egy elem. |
.gomb.veszelyes | 0 – 2 – 0 | Két osztály. |
li:nth-child(2n)::before | 0 – 1 – 2 | Egy pszeudo-osztály; két elem (li és ::before). |
li:not(.kesz) | 0 – 1 – 1 | A :not() maga nem számít, csak ami a zárójelében van. |
#menu a | 1 – 0 – 1 | Egy azonosító, egy elem. |
#menu .link:hover | 1 – 2 – 0 | Egy azonosító, egy osztály, egy pszeudo-osztály. |
Két különbözően megírt kijelölőnek is lehet pontosan ugyanakkora a specificitása. Ilyenkor a sorrend dönt — és ez gyakran okoz meglepetést.
<div class="kartya"> <p class="ar">3 490 Ft</p> </div>
/* 0 – 1 – 1 */
p.ar {
color: crimson;
font-weight: bold;
}
/* 0 – 1 – 1 — ugyanannyi! */
.kartya p {
color: gray;
}
p.ar sokkal
„célzottabbnak" tűnik. A két kijelölő specificitása azonos (0 – 1 – 1), tehát a
később írt nyert. A félkövérség megmaradt, mert azért nem volt verseny.
A 12. leckében láttuk, hogy CSS-t közvetlenül az elemre is írhatsz a style
attribútummal. Ez erősebb bármilyen kijelölőnél — még egy azonosítónál is.
Gondolj rá úgy, mint egy negyedik, mindent megelőző oszlopra.
<p id="cim" style="color: green;"> Milyen színű lettem? </p>
/* 1 – 0 – 0 */
#cim {
color: crimson;
}
Van egy vészfék: ha egy érték után odaírod, hogy !important, az a
deklaráció a kaszkád első lépésében nyer — megelőzve minden specificitást és még az
inline stílust is.
<p id="cim" class="szoveg" style="color: green;"> Milyen színű lettem? </p>
#cim {
color: crimson;
}
/* 0 – 1 – 0, DE !important */
.szoveg {
color: orange !important;
}
!important miatt.
Mert nem megoldja a problémát, hanem eltakarja. A tipikus történet:
!important. Működik!!important segít.Ha egy szabályod nem hat, derítsd ki, mi írja felül (10. pont), és oldd meg rendesen — például egy megfelelő osztállyal.
Ritka, tudatos esetekben: egy segédosztálynál, aminek garantáltan mindig érvényesülnie
kell (például .rejtett { display: none !important; }), vagy ha egy
külső, nem módosítható stíluslapot kell felülírni. Kezdőként ökölszabály:
ha kétségeid vannak, ne használd.
| # | Mi? |
|---|---|
| 1 | !important deklaráció |
| 2 | style attribútum (inline stílus) |
| 3 | Stíluslap szabálya — specificitás szerint, azon belül sorrend szerint |
| 4 | Örökölt érték a szülőtől (8. pont) |
| 5 | A böngésző alapértelmezése |
Eddig arról volt szó, mi történik, ha több szabály vonatkozik egy elemre. Most nézzük a fordítottját: mi van, ha egy sem?
Ilyenkor bizonyos tulajdonságok a szülőtől öröklődnek. Ha a
body elemnek megadod a betűtípust, az oldal összes szövege azt fogja
használni — nem kell minden bekezdésnek, címsornak és listaelemnek külön megadnod.
<div class="doboz">
<h3>Címsor a dobozban</h3>
<p>Bekezdés, benne egy
<strong>kiemelt</strong> szóval.</p>
</div>
.doboz {
/* ezek öröklődnek */
color: #be123c;
font-family: Georgia, serif;
/* ezek NEM öröklődnek */
border: 3px solid #be123c;
padding: 12px;
background-color: #fff5f7;
}
strong is bordó és Georgia
betűs — egyikre sem írtunk szabályt, a .doboz elemtől örökölték.
A keretet viszont csak a doboz kapta meg: a benne lévő bekezdésnek nincs saját kerete.
Ami a szöveg kinézetére vonatkozik, az általában öröklődik. Ami a doboz méretére, keretére, helyére vonatkozik, az nem. Gondolj bele, miért így logikus: ha a keret öröklődne, egy dobozban lévő minden bekezdés és minden szó köré is keret kerülne.
| ✔ Öröklődik | ✘ Nem öröklődik |
|---|---|
colorfont-family, font-size, font-weight, font-styleline-height, letter-spacingtext-align, text-transformlist-stylecursor, visibility
|
borderpadding, marginbackgroundwidth, heightdisplayposition
|
Ha egy olyan tulajdonságot, ami magától nem öröklődne, mégis a szülőtől szeretnél átvenni, írd
értéknek: inherit.
.kartya p {
border-color: inherit; /* vedd át a szülő keretszínét */
}
Az űrlapelemek (button, input,
select, textarea) a böngészők többségében
nem öröklik a betűtípust — ezért látod őket furcsa, eltérő betűvel. A megoldás, amit
érdemes minden stíluslap elejére betenni:
button, input, select, textarea { font: inherit; }
Ez a lecke legmeglepőbb szabálya, és a legtöbb „megmagyarázhatatlan" CSS-hibát ez okozza:
Ha egy elemre közvetlenül vonatkozik egy szabály, az mindig nyer az örökölt érték ellen — akármilyen gyenge is ez a szabály, és akármilyen erős volt az, amelyiktől a szülő az értékét kapta. Az öröklés csak akkor jut szóhoz, ha az elemre egyáltalán semmi nem vonatkozik.
<div id="tartalom"> <h3>Címsor</h3> <p>Milyen színű a bekezdés?</p> </div>
/* 1 – 0 – 0 — a SZÜLŐRE vonatkozik */
#tartalom {
color: crimson;
}
/* 0 – 0 – 1 — közvetlenül a p-re */
p {
color: blue;
}
p szabály közvetlenül rá vonatkozik, az örökölt érték
a versenybe be sem száll.
Ez magyarázza az egyik leggyakoribb kezdő kérdést: „Miért nem lett piros a link, ha a szülőjének piros színt adtam?"
<p class="figyelmeztetes"> Ez a szöveg bordó. Ez pedig egy <a href="#">link a mondatban</a>, ami nem lesz bordó. </p> <p class="figyelmeztetes jav"> Itt viszont a <a href="#">link is átveszi</a> a színt. </p>
.figyelmeztetes {
color: #be123c;
font-weight: bold;
}
/* a megoldás */
.jav a {
color: inherit;
}
a elemre (az adja a kék színt) — ez
közvetlenül a linkre vonatkozik, tehát legyőzi az örökölt bordót. A második bekezdésben a
color: inherit kifejezetten kéri az öröklést, és ez a célzott szabály már nyer.
Ugyanezért nem öröklik a címsorok a szülő betűméretét: a böngésző beépített stíluslapja közvetlenül ad nekik méretet. Minden elemnél, amelyiknek van alapértelmezett megjelenése (link, címsor, gomb, beviteli mező), számíts erre.
A jó hír: nem kell fejben számolgatnod. A böngésző fejlesztői eszköze pontosan megmutatja, mi történt. Jobb gomb az elemen → Vizsgálat (Inspect), majd a jobb oldali panel:
| Amit látsz | Mit jelent? |
|---|---|
| Styles fül, szabályok egymás alatt | Az elemre vonatkozó összes szabály, erősorrendben: legfelül a legerősebb. Mindegyik mellett ott van, melyik fájl melyik sorából jön. |
| Ez a deklaráció vesztett — egy feljebb lévő szabály felülírta. | |
| Inherited from … szakasz | A szülőktől örökölt értékek. Halványan jelennek meg azok, amelyek ennél az elemnél nem öröklődnek. |
| user agent stylesheet | A böngésző saját alapértelmezett szabálya — például a link kék színe. |
| Computed fül | A végső, ténylegesen érvényes érték minden tulajdonságra. Rákattintva megmutatja, melyik szabályból származik. |
| Egérrel a kijelölő fölé állva | Sok böngésző kiírja a kijelölő specificitását is. |
!important kulcsszóval.Az egész lecke egyetlen gyakorlati tanácsba sűríthető: tartsd alacsonyan és egyenletesen a specificitást. Ha a legtöbb szabályod nagyjából egyforma erős, a sorrend dönt — azt pedig te irányítod.
| Szokás | Miért jó? |
|---|---|
| Stílust osztályokkal írsz (0 – 1 – 0) | Egyforma erősek, könnyen felülírhatók egy későbbi osztállyal. |
| Azonosítót nem használsz stílushoz | Az 1 – 0 – 0 erőt csak újabb azonosítóval vagy !important kulcsszóval lehet legyőzni. |
| Rövid kijelölőket írsz | A hosszú lánc (.oldal .tartalom .kartya p) feleslegesen erős, és a HTML szerkezetéhez ragad. |
| Általánostól a speciális felé rendezed a fájlt | A sorrend magától jó irányba dolgozik. |
| Inline stílust nem írsz | A stíluslapból gyakorlatilag felülírhatatlan. |
!important kulcsszót nem írsz | Eltakarja a problémát, és újabb !important kulcsszavakat szül. |
| Az öröklődést kihasználod | A betűtípust és az alapszínt a body elemnél egyszer adod meg. |
#oldal .tartalom div.kartya p {
color: gray;
}
/* később nem működik, tehát: */
.kiemelt {
color: crimson !important;
}
.kartya-szoveg {
color: gray;
}
/* később, ugyanakkora erővel: */
.kartya-szoveg.kiemelt {
color: crimson;
}
Előbb válaszolj magadban, csak utána nézd meg a megoldást.
1. Számold ki a specificitást: .menu li a:hover
0 – 2 – 2. Egy osztály (.menu) és egy pszeudo-osztály (:hover) a második oszlopba; két elem (li, a) a harmadikba.
2. Melyik nyer: body div ul li p span vagy .cimke?
A .cimke. A hosszú lánc 0 – 0 – 6, az osztály 0 – 1 – 0. A második oszlopban az osztály vezet, és ott eldől a verseny — a harmadik oszlopot már meg sem nézik. A specificitás nem tízes számrendszer.
3. Két szabályod van: .kartya p { color: gray; } és utána p.ar { color: red; }. Milyen színű lesz a <p class="ar"> egy kártyában? És ha megcseréled a sorrendjüket?
Mindkettő 0 – 1 – 1, tehát döntetlen, és a sorrend dönt. Az eredeti sorrendben piros (a p.ar van később). Megcserélve szürke.
4. A szülő div elemnek #doboz { color: red; } szabályt adtál, a benne lévő bekezdésre pedig p { color: blue; } vonatkozik. Milyen színű a bekezdés, és miért?
Kék. Az azonosító a div elemre vonatkozik, nem a bekezdésre — a bekezdés csak örökölné a pirosat. Az örökölt értéknek viszont nincs specificitása: a közvetlenül a bekezdésre vonatkozó p szabály mindig nyer ellene.
5. A .hirdetes elemnek bordó színt adtál, de a benne lévő link kék maradt. Miért, és hogyan javítod?
A böngésző beépített stíluslapjában van egy közvetlenül az a elemre vonatkozó szabály (ez adja a kéket), és egy célzott szabály mindig legyőzi az örökölt értéket. Javítás: .hirdetes a { color: inherit; } — vagy közvetlenül megadod a link színét.
6. Mely tulajdonságok öröklődnek ezek közül: color, border, font-family, padding, text-align, background-color?
Öröklődik: color, font-family, text-align — ezek a szöveg kinézetére vonatkoznak. Nem öröklődik: border, padding, background-color — ezek a dobozra.
7. Egy szabályod nem működik. Egy osztálytársad azt tanácsolja: „Írj mögé !important kulcsszót, és kész." Mit válaszolsz?
Hogy ez csak eltakarja a problémát. Előbb F12-vel derítsem ki, melyik szabály írja felül (áthúzott deklaráció a Styles panelen), hasonlítsam össze a specificitásukat, és a kijelölők szintjén javítsam. Az !important később újabb !important kulcsszavakat követelne.
8. Mit jelent, ha az F12 → Styles panelen a deklarációd át van húzva?
Hogy a szabályod megérkezett és vonatkozik is az elemre, de erre a tulajdonságra egy erősebb szabály nyert. Ez a felette lévő, át nem húzott deklaráció.
!important) → specificitás → sorrend. Az első különbség eldönti.*, a kombinátorok és a vessző nem számítanak.style attribútum erősebb minden kijelölőnél; az !important még annál is.!important kulcsszó eltakarja a problémát — kerüld.color, font-*, text-align); nem öröklődik, ami a dobozra (border, padding, background).!important.