
CSS Псевдо Селектори
Освен обикновените класови селектори съществуват и псевдо класови селектори.
Псевдо класовете не са класове, които са описани в HTML структурата на страницата ни. Те са състояния на елементите, които зависят от нещо друго. Селекторите, които ги използват започват не с една, а с две точки (не последователни две точки, а просто двоеточие).
:hover
Най-често използваният псевдо клас е може би :hover
. Този псевдо клас се прилага към елементине, когато мишката е над тях. Основно това се сеща при линковете, когато да речем те сменят цвета си, когато мишката мине над тях или пък изгубват/придобиват подчертаваща линия.
a { color: #00F; }
a:hover { color: #F00; text-decoration: none; }
В примера линковете по подразбиране ще са сини и подчертани (подчертаването идва по принцип). Когато мишката е над тях ще стават червени, а подчертаващата линия ще изчезва.
:focus
Препоръчително е този псевдо клас да се използва в комбинация с :focus
. Този селектор оказва случаи, когато даденият елемент е на фокус. В уроците за HTML споменахме, че фокус по подразбиране могат да имат елементите от формуляри и връзките. Фокусът може да се променя с клавиша tab
. По този начин, на посетителите на сайта се показва точно кой елемент са фокусирали, ако използват клавиатурата си.
a:hover, a:focus { text-decoration: none; }
Това е просто добра практика за по достъпни сайтове, но никой не може да ви задължи да го правите. Сайтът ви няма да се определя като “счупен”, когато не прилагате тази практика.
:active
:active
псевдо класът пък се прилага към линкове когато в момента са кликнати, но преди още браузърът да е заредил новата страница. По-разпространено приложение може да има при линкове, които водят до вътрешна част от същата страница (href
атрибута им започва с “#”).
Линковете имат и други псевдо класове, като :link
и :visited
, които обозначават състояния съответно на все още не посетена връзка, както и на връзка, която вече е била последвана. В резултатите на Google ще забележите, че когато вече сте разглеждали дадена страница, тя се оцветява във виолетово, а не остава в синьо.
:lang
Псевдо клас за език на елемент е :lang(code)
, където трябва да замените “code” с реален езиков код, който да присъства в language=""
атрибута на HTML елемента. Еквивалентно е на [lang="code"]
атрибутен селектор, но все пак е различно :).
Псевдо елементи
Освен селекторите за псевдо класове съществуват и селектори за псевдо елементи, които отново се декларират с двоеточие.
:first-letter
Селекторът :first-letter
например се отнася само за първата буква от текста на даден елемент. Използвайки този селектор можете да създадете по-особен вид на първата буква от абзаца, или от статията, в която се намира този абзац — ефект срещан в различни книги.
:first-line
Подобно на :first-letter
съществува и :first-line
, който се отнася за първия ред.
:first-child
Като сме почнали с “първи” псевдо селектори — да споменем и :first-child
. Този псевдо клас (да — връщаме се малко на псевдо класове, стига само псевдо елементи) се прилага към елемента, само ако той е първи дъщерен елемент за родителя си. С помощта на следния код можем да направим така, че даден списък да има разграничаваща линия само между елементите, които го съставят, а не просто над всеки от тях:
ul li { border-top: 1px solid #000; }
ul li:first-child { border-top: none; }
Използвайки селектора просто оказваме първият елемент да няма гранична линия отгоре.
Подобно на :first-child
съществува и :last-child
.
:before и :after
Да се върнем пак малко на псевдо елементите. Можем да използваме селекторите :before
и :after
, за да добавим съдържание посредством CSS преди или след елемента.
Тук е малко спорно до каква степен това е удачно. В уроците за HTML казахме, че структурата и информацията от сайта се съдържа там. Сега обаче говорим за добавяне на съдържание, посредством CSS. А то дори няма да бъде забелязано от търсачките. В много случаи изкушението да използваме:
.required:after { content: ' Това поле е задължително'; }
когато правим формуляри надделява, но лично аз го считам за неправилно. Най-малко от езикова гледна точка правим сайта коректен само за българска (в примера) аудитория. Няма нищо лошо обаче да използваме едно езиково независимо:
.required:after { content: '*'; }
Просто звездичка. Всички са свикнали задължителна елементи от онлайн формуляр да се обозначават със звездичка, така че според мене поне е напълно нормално и правилно да го използваме.
Въпреки, че не дадох конкретни обяснения, за последните два примера, ми се струва, че и сами можете да се ориентирате, че съдържанието го вмъкваме след елементи с клас required, а самото съдържание, което добавяме се съдържа в content property-то на CSS дефиницията. Това, което не става ясно от предните два примера може да се види в следващия:
.required:after { content: '*'; color: #F00; font-weight: bold; }
Червеният цвят и удебеленият шрифт ще се приложат само за добавеното съдържание, а не към реалния текст, който се съдържа в елемента с клас required
.
Съществуват много приложения на :before
и :after
, но много от тях са сравнително сложни и не попадат в графата “първи стъпки”. Затова ще ги разгледаме в някои урок за по-напреднали. Пък и сами можете да потърсите в интернет — в крайна сметка аз тук давам само някаква база.
Някои CSS3 псевдо селектори
Първо да уточним, че това, което ви представих до момента беше CSS версия 2. Както сме говорили за HTML4 и за HTML5, така има и CSS2 и CSS3. Връзката между аналогиите е дори по-голяма, тъй като CSS2 беше разработен успоредно с HTML4 и се появиха на бял свят по едно и също време. HTML5 и CSS3 се разработват точно в момента и поддръжката им в различните браузъри също като че ли върви успоредно. Въпреки че е трудно да се правят подобни сравнения.
:first-of-type и :last-of-type
:first-of-type
и :last-of-type
псевдо класовете обхващат първи и последен елемент от даден тип. Приличат на :first-child
и :last-child
, но ще забележите разликата в следния html код:
<div class="article">
<h2>Заглавие</h2>
<p>Първи абзац</p>
<p>Втори абзац</p>
</div>
В случая :first-child
няма да хване първия параграф, тъй като преди него има заглавие, което реално е първото дете. Но :first-of-type
ни върши прекрасна работа, ако искаме да селектираме този първи параграф.
:nth-
:nth-of-type(xn + y)
— любимият ми псевдо клас, който има невероятна сила. Тук има и известна доза математика (спокойно — само линейни уравнения).
Първо да обясним смисълът на този селектор. Той обхваща всеки n-ти елемент от даден тип.
n-ти означава, че може да бъде всеки първи (няма смисъл, тъй като това означава просто всички), всеки втори, всеки трети и т.н.
Истинската сила обаче идва, когато зададем всеки трети, отместен с единица. Това ще рече първи, четвърти, седми и т.н. За повече яснота, нека разгледаме няколко примера и обясним особеностите при всеки:
Константа
:nth-of-type(2)
Това просто селектира втория елемент. Само него и нищо друго. Ако вместо 2 бяхме писали 3 — щеше да е третия. Следващият пример, обаче:
Коефициент
:nth-of-type(2n)
Вече селектира всеки втори елемент (втори, четвърти, шести и т.н.). Стилът се прилага за елементи, чиито номер подред отговарят на условието 2n
за някаква стойност на естественото n или 0 (0, 1, 2, 3 …).
За тия, които това ги обърква (моля, моля — само блондинките са оправдани това да ги затруднява!), селекторът поддържа вместо 2n
да напишем просто even (четни). Подобно можем да използваме и odd за нечетни:
tr:nth-of-type(even) { background-color: #333; }
tr:nth-of-type(odd) { background-color: #000; }
С този стил прилагаме тъмно сив фон на четните редове от таблица и черен фон на нечетните редове.
Коефициент + константа
Същата работа като odd можем да изразим и с:
:nth-of-type(2n+1) { background-color: #000; }
Добре, тука вече това 2n+1
може да затрудни не само блондинките, но пак не е сложно! Това, което постигаме в случая е, че селектираме всеки втори елемент (всеки четен) посредством 2n
и след това отместваме селекцията с 1 (благодарение на това +1
).
Така от всички четни стават всички нечетни. Можем да пишем и 2n+2
, но това ще има по-различен ефект, който ще уточним по-късно.
Въпреки, че 2n
и 2n+1
можем лесно да ги заменим с even
и odd
, за да направим елементите да редуват три цвята трябва да използваме следното:
tr:nth-of-type(3n) { background-color: #FFF; }
tr:nth-of-type(3n+1) { background-color: #090; }
tr:nth-of-type(3n+2) { background-color: #F00; }
По този начин направихме своя трибагреник – редуваме бяло, зелено и червено (после пак отначало).
По подобен начин могат да се направят толкова цветове, колкото искате.
Прескачане
Наистина интересното започва, когато напишем нещо от сорта на:
:nth-of-type(2n+4) { color: #F00; }
за подобен, на който споменахме по-рано.
Споменах, че n
е естествено число или 0 — нали? Естествените числа са цели положителни числа. Казахме, че прибавяме и нулата (за по-интересно).
Така излиза, че условието ни обхваща елементи започващи чак от номер 4 (в случай, когато n=0
), и продължават с всеки втори след това.
Отрицателен коефициент
:nth-of-type(-n+3) { color: #F00; }
От сега ще ви кажа, че това последното ще се отнася за първите три елемента.
Когато пред n
сложим знак минус излиза, че стойностите тогава вече се менят в реда 0, -1, -2 и т.н. Когато към тези числя прибавим 3 като краен резултат от условието получаваме елементи с пореден номер 3, 2 или 1, защото номерата на елементите ни също са естествени числа. В крайна сметка имаме само цели елементи и то положителни, ако са 0 — просто нямаме елементи, а отрицателни елементи няма как да се получат на практика.
Допълнителни четива:
За повече информация (и списъци на всички псевдо класове и псевдо елементи) може да разгледате и следните страници:
- CSS Pseudo-classes (английски)
- Псевдокласове (български)
- Pseudo-elements (английски)