3. modul · CSS alapok · 13. lecke
A CSS fele a megcélzás: pontosan azokat az elemeket kell eltalálnod, amiket formázni akarsz — se többet, se kevesebbet. Ebben a leckében megtanulod az összes alapvető kijelölőt, és azt a szóközt, ami két teljesen különböző dolgot jelenthet.
p.fontos, .doboz.kiemelt.+ és a ~ jellel.A kijelölő (angolul selector, magyarul szelektornak is hívjuk) a CSS-szabály első része: az a rész, ami a kapcsos zárójel előtt áll. Ez mondja meg a böngészőnek, hogy a szabály mely elemekre vonatkozik.
A kijelölő valójában egy kérdés az oldal fastruktúrájához (3. lecke): „add ide az összes olyan elemet, amelyik…". A böngésző végigfut a fán, összegyűjti a találatokat, és mindegyikre alkalmazza a szabályt. Ha nulla találat van, nem történik semmi — és hibaüzenetet sem kapsz.
| Kijelölő | Mit céloz meg? |
|---|---|
p | Minden p elemet |
.doboz | Minden elemet, amin ott a doboz osztály |
#fejlec | Azt az egy elemet, aminek az azonosítója fejlec |
* | Minden elemet |
h1, h2 | Minden h1-et és minden h2-t |
p.fontos | Azokat a p elemeket, amelyeken ott a fontos osztály |
.kartya p | A .kartya belsejében lévő összes p-t |
.menu > li | A .menu közvetlen li gyerekeit |
h2 + p | Azt a p-t, ami közvetlenül egy h2 után áll |
input[type="email"] | Az e-mail típusú beviteli mezőket |
A legegyszerűbb: leírod az elem nevét, pont, vessző és kettőskereszt nélkül. A szabály az oldal összes ilyen elemére vonatkozik.
<h2>Hozzávalók</h2> <p>Négy főre.</p> <ul> <li>burgonya</li> <li>tojás</li> </ul> <p>Jó étvágyat!</p>
h2 {
color: #be123c;
}
p {
color: #7c6b74;
font-style: italic;
}
li {
color: #0369a1;
}
Mi van, ha csak az egyik bekezdést akarod megváltoztatni? Az elemszelektorral sehogy. Ezért van szükség osztályokra — az következik.
Alapbeállításokhoz. „Minden bekezdés ilyen betűméretű", „minden link ilyen
színű", „a body ilyen betűtípusú". Ezek után jönnek az osztályok,
amik a kivételeket kezelik.
Ez lesz a munkalovad — a CSS-ed 80%-a osztályszelektor lesz. A HTML-ben
class="nev", a CSS-ben .nev,
ponttal az elején.
<p>Ez egy sima bekezdés.</p> <p class="fontos">Ez fontos!</p> <p>Ez megint sima.</p> <h3 class="fontos">Címsor is lehet fontos</h3> <li class="fontos">Listaelem is</li>
.fontos {
background-color: #fef3c7;
border-left: 4px solid #d97706;
padding: 6px 10px;
}
HTML-ben: class="fontos" — pont nélkül.
CSS-ben: .fontos { ... } — ponttal.
Ez a két leggyakoribb kezdő elgépelés: class=".fontos" a HTML-ben,
vagy fontos { } a CSS-ben. Egyik sem működik, és egyik sem ad hibaüzenetet.
A HTML-ben id="nev", a CSS-ben
#nev, kettőskereszttel. Mivel az azonosító oldalanként
egyedi, ez pontosan egy elemet céloz meg.
<div class="doboz">Első doboz</div> <div class="doboz" id="kiemelt">Kiemelt doboz</div> <div class="doboz">Harmadik doboz</div>
.doboz {
border: 1px solid #9ca3af;
padding: 8px 12px;
margin-bottom: 8px;
}
#kiemelt {
border-color: #be123c;
border-width: 3px;
background-color: #fff5f7;
}
.doboz szabály, de a középsőre
ráadásul a #kiemelt is. A két szabály
összeadódik, és ahol ütköznek (a keret színe és vastagsága), ott az azonosító nyer.
Stílusozáshoz lehetőleg ne azonosítót használj. Az azonosító a CSS-ben nagyon
„erős": később csak még erősebb szabállyal lehet felülírni, és ez gyorsan fájdalmassá válik.
(A 15. leckében kiderül, pontosan mennyivel erősebb.) Az id maradjon
a horgonyoké, a label for attribútumáé és a JavaScripté.
A * az oldal összes elemét megcélozza. Önmagában ritkán
használjuk, de van egy nagyon gyakori szerepe:
* {
box-sizing: border-box;
}
Ezt a három sort szinte minden stíluslap tartalmazza — hogy miért, azt a 17. leckében (dobozmodell) érted majd meg. Most csak ismerd fel.
A vesszővel elválasztott kijelölők mindegyikére vonatkozik a szabály. A 12. leckében már láttad; most nézzük meg vegyesen.
<h2>Címsor</h2> <p>Sima bekezdés.</p> <p class="megjegyzes">Megjegyzés.</p> <div id="lablec">Lábléc</div>
h2, .megjegyzes, #lablec {
font-family: Georgia, serif;
color: #be123c;
}
Ez a két sor teljesen mást céloz meg:
h2, .megjegyzes { ... }
h2 .megjegyzes { ... }
Egyetlen vessző a különbség. A jobb oldali valószínűleg semmit nem talál — és nem szól érte.
Ha két kijelölőt szóköz nélkül írsz egymás után, az azt jelenti: „ugyanaz az elem, ami mindkettőnek megfelel".
| Kijelölő | Mit jelent? |
|---|---|
p.fontos | Olyan p, amin ott a fontos osztály |
.doboz.kiemelt | Olyan elem, amin mindkét osztály rajta van |
div#fejlec | Olyan div, aminek az azonosítója fejlec |
<p class="uzenet">Csak üzenet</p> <p class="uzenet hiba">Üzenet + hiba</p> <p class="hiba">Csak hiba</p>
.uzenet {
border: 1px solid #9ca3af;
padding: 6px 10px;
margin-bottom: 6px;
}
.uzenet.hiba {
border-color: #be123c;
background-color: #fff5f7;
color: #be123c;
font-weight: bold;
}
.uzenet.hiba csak a középsőre hat — arra, amelyiken
mindkét osztály rajta van. A harmadik bekezdésen csak a hiba osztály
van, így semmit nem kapott (nincs önálló .hiba szabály).
Így építhetsz alap + változat rendszert: van egy .gomb
szabályod az összes gombra, és mellé .gomb.veszelyes,
.gomb.nagy szabályok a változatokra. A HTML-ben csak annyi a dolgod,
hogy a megfelelő osztályokat egymás mellé írod.
Most jön a lecke legfontosabb — és leggyakrabban félreértett — része. Ha két kijelölő közé szóközt teszel, az azt jelenti: „az elsőnek a belsejében lévő második".
p.fontos { ... }
Olyan p, amin rajta van a fontos osztály.
p .fontos { ... }
Olyan elem a fontos osztállyal, ami egy p belsejében van.
Ha véletlenül beütsz egy szóközt, a szabályod némán megszűnik működni. Ez a CSS egyik leggyakoribb, legnehezebben észrevehető hibája.
<p class="fontos"> Bekezdés a fontos osztállyal. </p> <p> Bekezdés, benne egy <span class="fontos">fontos span</span>. </p>
/* szóköz NÉLKÜL: maga a p */
p.fontos {
background-color: #fef3c7;
}
/* szóközzel: a p BELSEJÉBEN */
p .fontos {
background-color: #dcfce7;
font-weight: bold;
}
p viseli az osztályt),
a másodikban pedig csak a span zöld (ő van a p
belsejében). A két szabály soha nem cserélhető fel.
A leszármazott kijelölő nem csak a közvetlen gyerekeket találja meg, hanem az unokákat, dédunokákat is — bármilyen mélyen.
<div class="kartya">
<h3>Cím</h3>
<p>Közvetlen gyerek bekezdés.</p>
<div>
<div>
<p>Három szinttel mélyebben.</p>
</div>
</div>
</div>
<p>Kártyán KÍVÜLI bekezdés.</p>
.kartya p {
color: #be123c;
background-color: #fff5f7;
padding: 4px 8px;
}
Ha csak a közvetlen gyerekeket akarod megcélozni, a szóköz helyett
> jelet használsz.
> csak egy szintet lép lefelé, a szóköz bármennyit.<ul class="menu">
<li>Kezdőlap</li>
<li>Termékek
<ul>
<li>Kabátok</li>
<li>Cipők</li>
</ul>
</li>
<li>Kapcsolat</li>
</ul>
/* CSAK a közvetlen gyerekek */
.menu > li {
background-color: #fce7f3;
border-left: 4px solid #be123c;
padding-left: 6px;
margin-bottom: 4px;
}
ul gyerekei, nem a .menu elemé.
Szóközzel (.menu li) mind az öt megváltozott volna.
Leggyakrabban többszintű menüknél és egymásba ágyazott listáknál — ott, ahol
ugyanaz az elemtípus ismétlődik több szinten. Ha nincs beágyazás, a szóköz és a
> ugyanazt eredményezi — ilyenkor a szóköz az egyszerűbb.
Testvérek azok az elemek, amelyeknek ugyanaz a szülőjük. Két kijelölő van rájuk:
| Kijelölő | Mit céloz meg? |
|---|---|
h2 + p | Közvetlenül egy h2 után álló p — csak az egyet |
h2 ~ p | Az összes p, ami a h2 után áll (ugyanazon a szinten) |
<p>Bekezdés a címsor ELŐTT.</p> <h2>Címsor</h2> <p>Első bekezdés a címsor után.</p> <p>Második bekezdés.</p> <p>Harmadik bekezdés.</p>
/* CSAK a közvetlenül utána álló */
h2 + p {
font-weight: bold;
color: #be123c;
}
/* MINDEGYIK utána álló */
h2 ~ p {
border-left: 3px solid #fb7185;
padding-left: 8px;
}
A CSS-ben nincs „az előtte álló elem" kijelölő, és szülőt sem lehet megcélozni a gyerek alapján. A kijelölők mindig lefelé és előre mutatnak a fában. Ha ilyesmire van szükséged, általában az a jó megoldás, hogy adsz egy osztályt a megfelelő elemnek.
Tipikus eset: „a címsor utáni első bekezdés legyen bevezető stílusú", vagy
„két egymás után következő gomb közé kerüljön térköz"
(.gomb + .gomb { margin-left: 8px; }) — így az első gomb elé nem kerül
felesleges hely.
Elemeket attribútumaik alapján is megcélozhatsz, szögletes zárójellel. Ez főleg űrlapoknál és linkeknél hasznos.
| Kijelölő | Mit céloz meg? |
|---|---|
[required] | Minden elemet, amin van required attribútum (bármi az értéke) |
input[type="email"] | Azokat az inputokat, amiknek a típusa pontosan email |
a[href^="https"] | Linkek, amelyeknek a href attribútuma így kezdődik (^ = eleje) |
a[href$=".pdf"] | Linkek, amelyeknek a href attribútuma így végződik ($ = vége) |
a[href*="wiki"] | Linkek, amelyeknek a href attribútuma tartalmazza ezt (* = bárhol) |
<p> <label for="a">Név *</label><br> <input type="text" id="a" name="nev" required> </p> <p> <label for="b">E-mail *</label><br> <input type="email" id="b" name="email" required> </p> <p> <label for="c">Becenév</label><br> <input type="text" id="c" name="becenev"> </p>
input {
padding: 5px 8px;
border: 1px solid #9ca3af;
}
input[required] {
border-left: 4px solid #be123c;
}
input[type="email"] {
background-color: #eff6ff;
}
<p><a href="rolam.html">Belső link</a></p> <p><a href="https://wikipedia.org">Külső link</a></p> <p><a href="utmutato.pdf">Letölthető PDF</a></p>
a[href^="https"] {
color: #047857;
font-weight: bold;
}
a[href$=".pdf"] {
color: #be123c;
text-decoration: underline dotted;
}
href alapján. Ha holnap új PDF-linket teszel az oldalra,
az is automatikusan megkapja a stílust.
| Helyzet | Ajánlott kijelölő |
|---|---|
| Alapbeállítás minden ilyen elemre | Elemszelektor: p, a, body |
| Egy ismétlődő komponens (kártya, gomb, üzenet) | Osztály: .kartya — ez a fő eszköz |
| Ugyanannak a komponensnek egy változata | Két osztály: .gomb.veszelyes |
| „Ezen a részen belül minden…" | Leszármazott: .kartya p |
| Beágyazott listák, többszintű menü | Gyermek: .menu > li |
| Elemek közötti térköz, bevezető bekezdés | Testvér: .gomb + .gomb, h2 + p |
| Űrlapmezők típus szerint | Attribútum: input[type="email"] |
| Egyetlen, tényleg egyedi elem | Inkább osztály, mint azonosító |
div.oldal div.tartalom
ul.lista li a span { ... }
.menu-cimke { ... }
A hosszú lánc a HTML szerkezetéhez ragad: ha átrendezed a dobozokat, a szabály elromlik. Egy jól elnevezett osztály viszont ott marad az elemen, bárhova is kerül. Ha kettőnél több szintet láncolsz, gondold át, nem lenne-e jobb egy osztály.
| Hiba | Mi történik? |
|---|---|
Hiányzó pont: fontos { } |
A böngésző egy <fontos> nevű elemet keres. Ilyen nincs → nem történik semmi. |
Pont a HTML-ben: class=".fontos" |
Az osztály neve tényleg .fontos lesz — a .fontos szelektor így nem talál rá. |
Véletlen szóköz: p .fontos |
Nem a p-re hat, hanem a benne lévő elemre. Néma hiba. |
Hiányzó vessző: h1 h2 { } |
Nem „h1 és h2", hanem „h1 belsejében lévő h2" — ami általában nem létezik. |
| Elgépelt osztálynév | Nulla találat, nulla hibaüzenet. F12 → Styles: ha a szabály nem jelenik meg az elemnél, nem rá vonatkozik. |
| Túl hosszú lánc | Működik, de törékeny, és nehéz felülírni (15. lecke). |
Előbb válaszolj magadban, csak utána nézd meg a megoldást.
1. Mi a különbség a p.fontos és a p .fontos között?
p.fontos (szóköz nélkül): olyan bekezdés, amin rajta van a fontos osztály. p .fontos (szóközzel): olyan elem a fontos osztállyal, ami egy bekezdés belsejében van. Egy szóköz, két teljesen különböző jelentés.
2. Mit céloz meg ez: .kartya > p, és mit ez: .kartya p?
Az első csak a .kartya közvetlen bekezdés-gyerekeit. A második az összes bekezdést a kártyán belül, bármilyen mélyen — unokákat, dédunokákat is.
3. Mit jelent a vessző, és mit a szóköz két kijelölő között?
Vessző = „és": h1, h2 minden h1-re és minden h2-re hat. Szóköz = „belsejében": h1 h2 a h1-en belüli h2-t célozná meg (ami ritkán létezik).
4. Mikor hat a .doboz.kiemelt szabály egy elemre?
Csak akkor, ha az elemen mindkét osztály rajta van: class="doboz kiemelt". Ha csak az egyik, a szabály nem vonatkozik rá.
5. Hogyan adnál kék hátteret minden e-mail típusú beviteli mezőnek, osztály hozzáadása nélkül?
Attribútum-szelektorral: input[type="email"] { background-color: #eff6ff; }
6. Szeretnéd, hogy a címsor előtt álló bekezdés legyen kisebb betűs. Meg tudod ezt oldani kijelölővel?
Nem. A testvér-kijelölők csak előrefelé működnek (+ és ~), és szülőt sem lehet megcélozni a gyerek alapján. A megoldás: adj osztályt annak a bekezdésnek.
7. Miért rossz ez a szabály: div.oldal div.tartalom ul li a { color: red; }?
Mert a HTML pontos szerkezetéhez ragad: ha később átrendezed a dobozokat vagy kiveszel egy szintet, a szabály némán megszűnik működni. Ráadásul nagyon „erős", így később nehéz felülírni. Helyette adj egy beszédes osztályt a linknek, és arra hivatkozz.
8. A .fontos szabályod nem működik. Hogyan ellenőrzöd az F12-vel?
Jobb gomb az elemen → Vizsgálat, majd a jobb oldali Styles panel. Ha a szabály ott sincs, akkor a kijelölő nem talál rá (elgépelt név, véletlen szóköz, hiányzó pont). Ha ott van, de áthúzva, akkor egy erősebb szabály írta felül.
p = elemszelektor (alapbeállításokhoz) · .osztaly = a fő eszköz · #azonosito = egyetlen elem, stílushoz kerüld.class="fontos".* = minden elem · a, b = „a és b".p.fontos, .doboz.kiemelt).>: csak a közvetlen gyerek — egy szint lefelé.+: a közvetlenül utána álló testvér · ~: az összes utána álló testvér. Visszafelé nincs.[attr], [attr="ertek"], ^= (eleje), $= (vége), *= (tartalmazza).