От автора: псевдо-элементы используются уже в течение длительного времени. Тем не менее, есть некоторые случаи использования, которые, как мне кажется, не полностью известны разработчикам. Я написал эту статью, чтобы пролить свет на них, и чтобы их можно было использовать больше.
Эффект «наведение родитель-потомок»
Поскольку псевдо-элемент принадлежит своему родительскому элементу, для этого есть несколько необычных вариантов использования. А пока давайте рассмотрим простой пример, чтобы продемонстрировать, что я имею в виду.
В макете есть заголовок раздела с небольшим кружком слева от него. Когда мы наведем курсор на заголовок раздела, круг станет больше.
1 2 3 4 5 6 7 8 9 10 11 |
.section-title:before { content: ""; width: 20px; height: 20px; background: blue; /* Other styles */ } .section-title:hover:before { transform: scale(1.2); } |
Легко и просто. Давайте расширим эту концепцию более полезными вариантами использования.
Раздел проекта / блога
На моем сайте есть раздел, в котором перечислены все мои проекты. Я хотел добавить эскиз для каждого проекта, но для меня это не было приоритетом. Для меня важнее сама ссылка. Впервые я увидел этот эффект некоторое время назад на сайте Итана Маркотта.
Приведенный выше макет дизайна демонстрирует идею, которую я хотел применить. Каждая цветная ссылка в абзаце имеет связанный псевдо-элемент.
1 2 3 |
<section class="hero"> <p>Hello, my name is Ahmad. I’m a UX Designer and Front End Developer that enjoys the intersection between design and code. I write on <a href="www.ishadeed.com" class="link-1">ishadeed.com</a> and <a href="www.a11ymatters.com" class="link-2">a11ymatters.com</a> on CSS, UX Design and Web Accessibility.</p> </section> |
1) Я добавил отступы к разделу Hero
Я хочу зарезервировать место для псевдо-элементов, для этого предназначены отступы.
2) Позиционируем псевдо-элементы абсолютно
Чтобы позиционировать их абсолютно, мне нужно определить, с каким родителем они связаны. Обратите внимание на GIF ниже, как удаление position: relative для раздела .hero влияет на псевдо-элементы.
3) Добавление псевдо-элементов
Последний шаг — добавить псевдо-элементы вместе с эффектами наведения. Вот как я это сделал:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
.link-1 { color: #854FBB; } @media (min-width: 700px) { .link-1:after { content: ""; position: absolute; right: 0; top: 20px; width: 150px; height: 100px; background: currentColor; opacity: 0.85; transition: 0.3s ease-out; } .link-1:hover { text-decoration: underline; } .link-1:hover:after { transform: scale(1.2); opacity: 1; } } |
Обратите внимание, что я использовал currentColor для фона псевдо-элемента. Если вам не знакомо это ключевое слово, оно задает наследование от значения color его родителя. Поэтому в любой момент, когда я захочу изменить цвета ссылок, их легко изменить только один раз.
Если вам интересно, перейдите на главную страницу моего сайта и откройте раздел «Мои проекты». Я использовал там данную технику.
Увеличение размера кликабельной области
При добавлении псевдо-элемента к ссылке, кликабельная область вокруг становится больше. Это очень полезно и улучшает опыт пользователя. Давайте рассмотрим пример:
Кроме того, он может быть использован для расширения области клика компонента карточки, который имеет ссылку «Смотреть больше».
Наложения
Давайте предположим, что у нас есть элемент с фоновым изображением, а дизайн содержит наложение градиента с режимом наложения color. В этом могут помочь псевдо-элементы!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
.hero { position: relative; height: 300px; background: url("image.jpg") center/cover; } .hero:after { content: ""; position: absolute; left: 0; top: 0; width: 100%; height: 100%; background-image: linear-gradient(180deg, #851717 0%, #30328C 100%); mix-blend-mode: color; } |
Закругленные тени
Я не уверен, что правильное название, но это то, что у меня получилось. В те времена я использовал тени, которые закруглены по краям. Угадай, что! Можно создавать их с помощью псевдо-элемента.
Создание элемента
Я создал элемент div с обычными стилями, как показано ниже.
1 2 3 4 5 6 7 8 9 10 11 12 |
.elem { position: relative; display: flex; align-items: center; max-width: 400px; background: #fff; padding: 2rem 1rem; font-size: 1.5rem; margin: 2rem auto; text-align: center; box-sizing: border-box; } |
Добавление псевдо-элементов
Затем я добавил псевдо-элементы :before и :after с шириной 50% для каждого из них (для целей демонстрации я добавил им разные фоны).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
.elem:before, .elem:after { content: ""; position: absolute; top: 2px; width: 50%; height: 100%; } .elem:before { left: 0; background: grey; } .elem:after { right: 0; background: #000; } |
Далее я добавлю, transform: skew(x), где Х будет 2 градуса. Для одного из них Х должен быть отрицательным.
1 2 3 4 5 6 7 |
.elem:before { transform: skew(-2deg); } .elem:after { transform: skew(2deg); } |
Далее я добавлю к каждому псевдо-элементу z-index: -1, чтобы переместить их на задний план.
После этого я сделал следующее:
добавил filter: blur
Уменьшил непрозрачность
Добавил градиент от прозрачного к черному (чтобы скрыть края псевдо-элементов в верхнем центре родителя)
Окончательный код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
.elem { position: relative; display: flex; align-items: center; max-width: 400px; background: #fff; padding: 2rem 1rem; font-size: 1.5rem; margin: 2rem auto; text-align: center; box-sizing: border-box; } .elem:before, .elem:after { content: ""; position: absolute; top: 3px; width: 50%; height: 100%; z-index: -1; background: linear-gradient(to bottom, transparent, #000); filter: blur(3px); opacity: 0.3; } .elem:before { left: 0; transform: skewY(-2deg); } .elem:after { right: 0; transform: skewY(2deg); } |
Существует еще один вариант — поменять местами значения skewY для :before и :after. Это даст другой эффект.
Использование :After или :Before
Из недавнего обсуждения в Твиттере я узнал, что лучше использовать :before вместо :after. Почему? Потому что при использовании :after может потребоваться добавить z-index к другим вложенным элементам, чтобы псевдо-элемент не перекрывал их. Давайте возьмем реальный пример.
Вот простая карточка, которая состоит из миниатюры и заголовка. Если вы заметили, под текстом есть наложение градиента, чтобы сделать текст более четким в случае, если изображение слишком светлое.
1 2 3 4 |
<article class="card"> <img src="article.jpg" alt=""> <h2>Title here</h2> </article> |
Чтобы добавить наложение градиента под текстом, мне нужно будет использовать псевдо-элемент. Какой из них вы выберете? :before или :after? Давайте рассмотрим оба.
1) :after
В этом случае заголовок появится под наложением псевдо-элемента, как показано ниже.
Решение этой проблемы заключается в добавлении z-index к заголовку карточки. Даже если это простое и быстрое решение, это не правильно.
1 2 3 4 |
.card-title { /*Other styles*/ z-index: 1; } |
2) :before
При использовании элемента :before для наложения он работает по умолчанию! Не нужно добавлять z-index к заголовку карточки. Причина в том, что :before не будет отображаться над другими элементами, как :after.
Стилизация ссылок на основе расширения файла
Например, если у нас есть ссылка с файлом PDF, можно добавить иконку PDF, чтобы сделать ее более понятной для пользователя. Вот пример того, как отобразить иконку PDF для ссылки:
1 2 |
<p><a href="example.pdf">Download PDF</a></p> <p><a href="example.doc">Download Doc</a></p> |
1 2 3 4 5 6 7 8 9 10 |
a[href$=".pdf"]:before { content: ""; display: inline-block; vertical-align: middle; margin-right: 8px; width: 18px; height: 18px; background: url(//s3-us-west-2.amazonaws.com/s.cdpn.io/182774/np_pdf_377198_000000.svg) center/20px no-repeat; padding: 3px; } |
Разделитель
В этом примере у нас есть разделитель с «or». С каждой его стороны у нас есть линия. Это можно сделать с помощью псевдо-элементов и Flexbox.
1 |
<p>Or</p> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
p { display: flex; align-items: center; } p:before, p:after { content: ""; height: 2px; background: #c5c5c5; flex-grow: 1; } p:before { margin-right: 10px; } p:after { margin-left: 10px; } |
Обновление
Оказалось, что есть лучший способ сделать это. Мистер Скотт Зиркель отметил, что для такого рода вещей лучше использовать hr. Посмотрите демо на CodePen.
Автор: Ahmad Shadeed
Источник: //ishadeed.com
Редакция: Команда webformyself.