Исчерпывающее руководство по псевдоэлементам и псевдоклассам в CSS

Одинарное или двойное двоеточие для ПЭ?

Когда (не) использовать CSS сгенерированное содержимое

  • Он не будет доступен для большинства программ чтения с экрана.
  • Его нельзя будет выделить.
  • Если контент содержит избыточную декоративную информацию, программы чтения с экрана, которые поддерживают CSS content, будут читать его вслух. Это будет убийственно для UX.

Экспериментальные псевдоклассы и псевдоэлементы

Псевдоклассы

Состояния

:link

a:link {
color: orange;
}
a {
color: orange;
}

:visited

a:visited {
color: blue;
}

:hover

a:hover {
color: orange;
}

:active

a:active {
color: rebeccapurple;
}

:focus

a:focus {
color: green;
}
input:focus {
background: #eee;
}

Бонус: SASS миксины для ссылок

@mixin links ($link, $visited, $hover, $active) {
& {
color: $link;
&:visited {
color: $visited;
}
&:hover {
color: $hover;
}
&:active, &:focus {
color: $active;
}
}
}
a {
@include links(orange, blue, yellow, teal);
}
a {
color: orange;
}
a:visited {
color: blue;
}
a:hover {
color: yellow;
}
a:active, a:focus {
color: teal;
}

Структура

:first-child

<ul>
<li>This text will be orange.</li>
<li>Lorem ipsum dolor sit amet.</li>
<li>Lorem ipsum dolor sit amet.</li>
</ul>
li:first-child {
color: orange;
}

:first-of-type

<ul>
<li>This text will be orange.</li>
<li>Lorem ipsum dolor sit amet. <span>This text will be orange.</span></li>
<li>Lorem ipsum dolor sit amet.</li>
</ul>
ul :first-of-type {
color: orange;
}

:last-child

<ul>
<li>Lorem ipsum dolor sit amet.</li>
<li>Lorem ipsum dolor sit amet.</li>
<li>This text will be orange.</li>
</ul>
li:last-child {
color: orange;
}

:last-of-type

<ul>
<li>Lorem ipsum dolor sit amet. <span>Lorem ipsum dolor sit amet.</span> <span>This text will be orange.</span></li>
<li>Lorem ipsum dolor sit amet.</li>
<li>This text will be orange.</li>
</ul>
ul :last-of-type {
color: orange;
}

:not

<ul>
<li class="first-item">Lorem ipsum dolor sit amet.</li>
<li>Lorem ipsum dolor sit amet.</li>
<li>Lorem ipsum dolor sit amet.</li>
<li>Lorem ipsum dolor sit amet.</li>
</ul>
li:not(.first-item) {
color: orange;
}
li:not(.first-item):not(:last-of-type) {
background: yellow;
color: black;
}

:nth-child

  • a является числом (именуется целым числом);
  • n это буква n (другими словами мы действительно пишем букву n в формуле);
  • + это оператор который может быть как плюсом (+) так и минусом (-);
  • b представляет собой целое число, как правило, но используется только там где необходим.
<ol>
<li>Alpha</li>
<li>Beta</li>
<li>Gamma</li>
<li>Delta</li>
<li>Epsilon</li>
<li>Zeta</li>
<li>Eta</li>
<li>Theta</li>
<li>Iota</li>
<li>Kappa</li>
</ol>
ol :nth-child(2) {
color: orange;
}
ol :nth-child(2n) {
color: orange;
}
ol :nth-child(even) {
color: orange;
}
ol :nth-child(2n+6) {
color: orange;
}

:nth-last-child

ol :nth-last-child(2) {
color: orange;
}
ol :nth-last-child(2n) {
color: orange;
}
ol :nth-last-child(even) {
color: orange;
}
ol :nth-last-child(2n+6) {
color: orange;
}

:nth-of-type

<article>
<h1>Heading Goes Here</h1>
<p>Lorem ipsum dolor sit amet.</p>
<a href=""><img src="images/rwd.png" alt="Mastering RWD"></a>
<p>This text will be orange.</p>
</article>
p:nth-of-type(2) {
color: orange;
}

:nth-last-of-type

</article>
</h1>Heading Goes Here</article>/h1>
</p>This text will be orange.</p>
</a href="#"><img src="images/rwd.png" alt="Mastering RWD"></a>
</p>Lorem ipsum dolor sit amet.</p>
</article>
p:nth-last-of-type(2) {
color: orange;
}

:only-child

<ul>
<li>This text will be orange.</li>
</ul>
<ul>
<li>Lorem ipsum dolor sit amet.</li>
<li>Lorem ipsum dolor sit amet.</li>
</ul>
ul :only-child {
color: orange;
}

:only-of-type

<ul>
<li>This text will be orange.</li>
</ul>
<ul>
<li>Lorem ipsum dolor sit amet.</li>
<li>Lorem ipsum dolor sit amet.</li>
</ul>
li:only-of-type {
color: orange;
}

:target

<article id="target">
<h1><code>:target</code> pseudo-class</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit!</p>
</article>
:target {
background: yellow;
}

Валидация

:checked

:default

:disabled

<input type="text" id="name" disabled>
:disabled {
opacity: 0.5;
}

:empty

  • Пустой
    Нет никакого содержимого или символов внутри элемента. Html-комментарий внутри элемента в данном случае не считается.
  • Не пустой
    Символы отображаются внутри элемента. Даже пробел считается.
  • верхний контейнер содержит текст, поэтому у него будет оранжевый фон;
  • во втором контейнере пробел, который считается контентом, поэтому он так же будет с оранжевым фоном;
  • в третьем контейнере ничего нет (он пуст), поэтому у него будет желтый фон;
  • и наконец последний контейнер содержит только html-комментарий (он так же пуст), поэтому и у него будет желтый фон.
<div>This box is orange</div>
<div> </div>
<div></div>
<div><!-- This comment is not considered content --></div>
div {
background: orange;
height: 30px;
width: 200px;
}
div:empty {
background: yellow;
}

:enabled

:enabled {
opacity: 1;
border: 1px solid green;
}

:in-range

<input type="number" min="5" max="10">
input[type=number] {
border: 5px solid orange;
}
input[type=number]:in-range {
border: 5px solid green;
}

:out-of-range

<input id="months" name="months" type="number" min="1" max="12">
input[type=number]:out-of-range {
border: 1px solid orange;
}

:indeterminate

<ul>
<li>
<input type="radio" name="list" id="option1">
<label for="option1">Option 1</label>
</li>
<li>
<input type="radio" name="list" id="option2">
<label for="option2">Option 2</label>
</li>
<li>
<input type="radio" name="list" id="option3">
<label for="option3">Option 3</label>
</li>
</ul>
:indeterminate + label {
background: orange;
}

:valid

input[type=email]:valid {
border: 1px solid green;
}

:invalid

input[type=email]:invalid {
background: orange;
}

:optional

<input type="number">
:optional {
color: gray;
}

:read-only

<input type="text" value="I am read only" readonly>
input:read-only {
color: gray;
}

:read-write

<div class="editable" contenteditable>
<h1>Click on this text to edit it</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit!</p>
</div>
:read-write:focus {
padding: 5px;
border: 1px dotted black;
}

:required

<input type="email" required>
:required {
color: black;
font-weight: bold;
}

:scope (эксперимент)

<article>
<section>
<h1>Lorem ipsum dolor sit amet</h1>
<p>Lorem ipsum dolor sit amet.</p>
</section>
<section>
<style scoped>
:scope {
font-style: italic;
}
</style>

<h1>This text will be italicized</h1>
<p>This text will be italicized.</p>
</section>
</article>

Язык

:dir (эксперимент)

<article dir="rtl">
<p>التدليك واحد من أقدم العلوم الصحية التي عرفها الانسان والذي يتم استخدامه لأغراض الشفاء منذ ولاده الطفل.</p>
</article>
/* prefixed */
article :-moz-dir(rtl) {
color: orange;
}
/* unprefixed */
article :dir(rtl) {
color: orange;
}
<article dir="ltr">
<p>If you already know some HTML and CSS and understand the principles of responsive web design, then this book is for you.</p>
</article>
/* prefixed */
article :-moz-dir(ltr) {
color: blue;
}
/* unprefixed */
article :dir(ltr) {
color: blue;
}

:lang

<article lang="en">
<q>Lorem ipsum dolor sit amet.</q>
</article>
<article lang="fr">
<q>Lorem ipsum dolor sit amet.</q>
</article>
<article lang="de">
<q>Lorem ipsum dolor sit amet.</q>
</article>
:lang(en) q { quotes: '“' '”'; }
:lang(fr) q { quotes: '«' '»'; }
:lang(de) q { quotes: '»' '«'; }

Прочее

:root

:root {
background: orange;
}

:fullscreen (эксперимент)

<h1 id="element">This heading will have a solid background color in full-screen mode.</h1>
<button onclick="var el = document.getElementById('element'); el.webkitRequestFullscreen();">Trigger full screen!</button>
h1:fullscreen {
background: orange;
}

Псевдоэлементы

::before/:before

<h1>Ricardo</h1>
h1:before {
content: "Hello "; /* Note the space after the word Hello. */
}
Hello Ricardo!

::after/:after

<h1>Ricardo</h1>
h1:after {
content: ", Web Designer!";
}
Ricardo, Web Designer!

::backdrop (эксперимент)

<h1 id="element">This heading will have a solid background color in full-screen mode.</h1>
<button onclick="var el = document.getElementById('element'); el.webkitRequestFullscreen();">Trigger full screen!</button>
h1:fullscreen::backdrop {
background: orange;
}

::first-letter/:first-letter

h1:first-letter  {
font-size: 5em;
}

::first-line/:first-line

p:first-line {
background: orange;
}

::selection

::-moz-selection {
color: orange;
background: #333;
}
::selection {
color: orange;
background: #333;
}

::placeholder (эксперимент)

<input type="email" placeholder="name@domain.com">
input::-moz-placeholder {
color:#666;
}
input::-webkit-input-placeholder {
color:#666;
}
/* IE 10 only */
input:-ms-input-placeholder {
color:#666;
}
/* Firefox 18 and below */
input:-moz-input-placeholder {
color:#666;
}

Заключение

--

--

Frontend-дева. Верстаю, пишу и перевожу статьи, менторю, выступаю. Поддержать переводы: https://www.tinkoff.ru/sl/2QSPTULCQcC

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Workafrolic (±∞)

Workafrolic (±∞)

3.6K Followers

Frontend-дева. Верстаю, пишу и перевожу статьи, менторю, выступаю. Поддержать переводы: https://www.tinkoff.ru/sl/2QSPTULCQcC