Псевдокласс focus-within в CSS


Содержание

Псевдокласс :focus-within в CSS

Не у каждого пользователя интернета есть мышка под рукой. При чтении со смартфона это очевидно! К тому же есть и другие способы ввода, которыми люди решают свои задачи. И для них нужны стили для фокуса.

Люди сложно устроены. Мы не всегда последовательны, а наши решения не всегда выглядят логичными. Порой мы даже делаем что-то просто так. Нам легко надоедает возиться и ковыряться с вещами, чтобы они лучше соответствовали нашим потребностям, независимо от их первоначального предназначения.

Люди также смертны. Мы можем заболеть или пораниться, случаются и обе беды сразу. Иногда это на время, а иногда — на всю жизнь. Как бы то ни было, порой привычные способы добиться нужного или желаемого бывают нам недоступны.

Люди также живут не в вакууме. Иногда нашим привычным действиям противостоят окружающая среда и внешние факторы. Вы когда-либо застревали в доме своих родителей на время праздников, когда вам приходилось пользоваться их древним, но ещё рабочим настольным компьютером? Ну вот.

Как мышь, так и сенсорный ввод служат индикатором для взаимодействия. Для сенсора это ясно: палец — связующее звено между вашим разумом и предметом на экране, который ему нужно активировать. В случае мыши, курсор служит посредником для вашего пальца.

Однако, есть ещё множество других форм ввода. Клавиатуры есть повсюду и могут практически полностью заменить мышь или сенсорный ввод, если знать нужные клавиши для нажатия в правильном порядке. Иногда это проще и быстрее мыши!

Вспомните, когда вы в последний раз использовали функциональность «Вырезать», «Копировать», «Вставить» и «Сохранить». Возможно, во время работы с таблицей, например, с Excel? Вы переключались между мышкой и клавиатурой, чтобы работать эффективнее? Вероятно, вы делали это «на автомате», но это яркий пример переключения ввода на лету ради быстрого результата. Да чёрт возьми, может во время этого нудного занятия у вас ещё нашлось время, чтобы лайкнуть чью-либо запись в Facebook на смартфоне.

Если обстоятельства мешают вам вводить информацию руками, то есть и другие варианты: манипуляторы, которые крепятся к голове или управляются ртом, кнопки-переключатели, устройства, управляемые вдуванием и вытягиванием воздуха из трубки, технологии распознавания голоса и отслеживания взгляда — всё это может служить для ввода в цифровой системе. Эти устройства идентифицируют область содержимого и активируют её. Напоминает хождение по ячейкам таблицы с помощью табуляции, когда ячейки подсвечиваются и готовы к редактированию. Это как по нажатию клавиши табуляции подсвечивается следующая ячейка в таблице, указывая на то, что в нее переместились для редактирования.

На этом видео, редактор видеороликов и консультант по доступности Кристофер Хилс демонстрирует возможности «Switch Control», программного обеспечения, помогающего людям с нарушением двигательной функции использовать аппаратные переключатели для работы со своими вычислительными устройствами.

Возможно это технология когда-нибудь пригодится и вам. К примеру, вы сломали обе руки, неудачно покатавшись на горном велосипеде, и хотите заказать что-нибудь вкусненькое с доставкой себе в утешение, пока вы поправляетесь. Или, скажем, едете за рулём и хотите безопасно написать эсэмэску своей семье. Или просто состаритесь. Навскидку полно и других примеров, просто люди обычно гонят от себя подобные мысли.

Если это интерактивно, этому нужен стиль фокуса

Не всегда известно, кто посещает наши сайты или приложения, причину их посещения, мотивы, время посещения, в каких условиях они находятся, какие эмоции испытывают, или какой ввод они могут использовать. Аналитика может помочь отчасти, но не даст полную картину. Было бы глупо ставить телегу впереди лошади и оптимизировать всю логику интерфейса лишь по этой обрывочной информации.

Также важно знать, что не все пользователи вспомогательных технологий хотят это афишировать. Да они и не обязаны. Продвинутые пользователи, использующие сочетания клавиш, специализированное программное обеспечение и браузерные расширения могут показаться пользователями вспомогательных технологий, но вполне могут и не быть инвалидами. Опять же, люди сложны!

Главное, дать эту возможность всем независимо ни от чего.

Идентификация и активация

:focus

Как с помощью этих альтернативных форм ввода можно определить, что это подходит для активации? К счастью, в CSS это решено — мы используем селекторы :focus и :active .

Они довольно просты. Хотите обвести ссылку оранжевым, когда пользователь переведет на неё фокус? Вот как это описать:

Этот контур появится, когда кто-то переместится к ссылке, будь то клик, касание сенсора, переход клавишей Tab с клавиатуры или ввод с помощью кнопки-переключателя, чтобы выделить её.

Есть популярное заблуждение, будто к стилям фокуса можно применить только свойство outline Отмечу, что :focus — это такой же селектор, как и любой другой, а значит, он принимает любые CSS-свойства. Я люблю играть с фоновым цветом, подчёркиванием и другими приемами, не влияющими на текущий размер компонента, чтобы не сдвигать раскладку страницы при активации селектора.

Затем, скажем, нужно удалить подчёркивание активированной ссылки, чтобы сообщить о смене состояния. Помните: ссылки используют подчёркивание!

Важно, чтобы все изменения состояния — из обычного в состояние под фокусом, а оттуда в активное — различались. Это значит, что каждый переход должен быть уникальным по сравнению с другими состояниями компонента, указывая пользователю на изменение.

Смена состояния также не должна ограничиваться лишь сменой цвета — не забывайте о людях с дальтонизмом и/или плохим зрением. Вот как изменение только лишь состояния цвета может выглядеть для человека с дейтеранопией, или неспособностью различать красный и зеленый цвета:

Чтобы лучше проиллюстрировать проблему, я намеренно удалил подчёркивание и браузерную нативную обводку фокуса из ссылки на видео. Если перебирать всё интерактивное на странице клавишей Tab, эту ссылку можно сразу и не заметить. Если человек не различает цвета, он не увидит и изменения ее состояния при наведении, а если у него к тому же катаракта — то и подавно.

:focus-within

:focus-within — связанный с фокусом селектор псевдокласса, название которого, «фокус внутри», звучит очень по-дзенски — может применять стили к родительскому элементу, когда один из его дочерних элементов получает фокус.

Типичный случай, когда этот селектор может быть нужен — если надо применить стили ко всей форме, когда один из элементов input в ней получает фокус. В примере ниже я плавно увеличиваю размер всей формы, если только пользователь не пожелал ограничить анимации до минимума.

Этот селектор по-прежнему относительно новый, поэтому я уверен, что со временем найдется гораздо больше интересных вариантов его использования.

Взгляды

У людей также есть мнения. К сожалению, порой эти мнения не подкреплены знаниями. Среди людей, не занимающихся доступностью, господствует мнение, что стили фокуса «безобразны», и многие дизайнеры и разработчики удаляют их ради внешнего лоска. А порой они даже не подозревают, что распространяют чужое мнение — многие CSS-сбросы включают глобальное удаление стилей фокуса, и включаются в проект в качестве фундаментальной зависимости, как что-то само собой разумеющееся.

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

:focus-visible

Правда жизни в том, что порой люди настаивают на удалении стилей фокуса, и у них бывает достаточно влияния, чтобы навязать это своему окружению. Это идет вразрез с правилами, что на действительно доступных сайтах механизмы фокуса должны быть видимыми. Эту проблему решает псевдоселектор :focus-visible .

Псевдокласс :focus-visible срабатывает, когда браузер определил, что произошло событие фокуса, и специальные встроенные эвристики подсказали ему, что имел место ввод без указателя. Или, если не такими мудрёными словами — он показывает стили для фокуса, если элемент активирован не курсором мыши и не пальцем на сенсоре.

На видеозаписи этого примера с Codepen видно, как в зависимости от того, каким способом пользователь выбирает ссылку, к ней применяются разные стили. При наведении и клике по ссылке мышью удаляется её подчёркивание, а сама она немного сдвигается вниз. При переходе к ней клавишей Tab с клавиатуры :focus-visible вместо этого применяет к ссылке яркий цвет фона.

Недавно Chromium заявил о своём намерении реализовать :focus-visible . Несмотря на сегодняшнюю скудную поддержку браузерами, есть полифил. Вместе с :focus-within они находятся в редакторском черновике селекторов четвёртого уровня, и со временем их начнут поддерживать все основные браузеры.

Вы можете знать :focus-visible под другим названием :-moz-focusring . Так, в виде псевдоселектора с префиксом, эту же идею реализовала Mozilla, еще за семь лет до предложения :focus-visible . В отличие от других браузерных префиксов CSS, нам не придётся беспокоиться о поддержке авторасстановки префиксов! Firefox признает как объявление :focus-visible , так и :moz-focusring , гарантируя, что между двумя браузерами будет паритет для наших названий селекторов.

Шаг вперёд, шаг назад

С браузерной поддержкой не всё гладко — одними лишь Chrome и Firefox веб не ограничивается. Пусть полифил отлично справляется там, где нет нативной поддержки, мы всё равно загружаем лишние данные, получаем дополнительную сложность в поддержке и более хрупкий код.

Также стоит отметить, что теперь нет такого четкого противопоставления двух классов устройств по типу ввода, как было раньше. Флагманский компьютер Surface от Microsoft предлагает клавиатуру, трекпад, стилус, камеру, голос и сенсорную функциональность из коробки. Исследование использования скринридеров WebAIM в 2020 г. показало, что мобильные устройства могут дополняться клавиатурным вводом чаще чем вы думаете. Эвристика — это хорошо, но как и аналитика, она не даёт полной картины.

Стоит учесть еще и то, что пользователям с мышкой тоже бывают нужны стили для фокуса. Эти стили — чёткий и однозначный признак интерактивности, что даёт большое преимущество людям с плохим зрением, когнитивными проблемами, и людям, которые не очень дружат с техникой. Особо продвинутые пользователи, которые не понаслышке знают, что скринридеры и горячие клавиши — это как Vim по сравнению с графическими оболочками, захотят, чтобы состояние фокуса было очевидным, ведь они порхают по экрану, используя клавиатуру.

Залог надёжного и устойчивого веба — это крепкая базовая функциональность, работающая в любом браузере. У ванильного селектора :focus настолько широкая поддержка, что можно быть уверенным, что даже экзотические браузеры его поймут.

В мире полно вещей, которые одним кажутся безобразными, а другим красивыми. Лично для меня стили фокуса не помеха. Как дизайнеру, мне кажется, что это необходимая часть создания зрелой системы дизайна. Как для разработчика, описывать состояние для меня — привычная работа. Как человеку, мне нравится сохранять интернет открытым и доступным, каким он и должен быть.

Если есть желание продвинуться в этой теме ещё дальше, дизайнер интерфейсов Кэйтлин Джийер отлично написала про индикаторы фокуса.

Псевдоклассы CSS :focus, :hover и :active

Если вы работали с CSS, то знаете, что стили применяются к селекторам, которые, в свою очередь, являются HTML-элементами. Но не всегда. Существует фантомная категория классов, которая возникает только в определенных состояниях объекта. Например, нажатая кнопка или выбранное поле ввода. Для таких особых случаев существуют псевдоклассы CSS :focus, :hover, :active.

Динамические псевдоклассы

CSS определяет три динамических псевдокласса, :focus, :hover, :active. Они меняют внешний вид объекта при определенных действиях пользователя. Это означает что для их появления нужно обязательное условие:

В этом примере, пока пользователь не наведет курсор мышки на элемент с классом button, записанные в :hover стили никак не проявятся.

Традиционно псевдоклассы используют для обработки ссылок и кнопок. Но диапазон возможностей гораздо шире. В CSS :focus ссылается на объект веб-страницы, которому принадлежит фокус ввода. Чаще всего это поля форм регистрации и поиска.

:hover отвечает за элементы, над которыми размещен указатель мышки или другого устройства. В момент когда пользователь активирует какой-то объект на странице, например, кликает по ссылке, появляется псевдокласс :active

Возможности применения псевдоклассов

Стили для :active, :focus, :hover — это своеобразный способ общения с пользователем. Так вы подсказываете куда вводить данные, подчеркивает ссылки, выделяете элементы по которым можно нажать. С помощью удачных эффектов вы мотивируете посетителя ввести адрес электронной почты и подписаться на вашу рассылку. Благодаря красивым кнопкам «Войти!», «Читать дальше!» у тех, кто случайно попал на страницу, возникнет желание путешествовать по сайту дальше.

Но не применяйте псевдоклассы слишком усердно. Если вы добавите :hover почти ко всем элементам, у посетителей вашего сайта может начаться морская болезнь от массы увеличивающихся или мигающих объектов. Применяйте CSS псевдо-класс focus для изменения цвета рамки полей, не более. Лучший способ грамотно назначить :hover — это сделать цвет шрифта темнее при наведении мышки. Но не трогайте размер — от этого могут пострадать соседние элементы.

Илон Маск рекомендует:  Что такое код cpdf_set_action_url

CSS псевдокласс :focus

Значение и применение

Псевдокласс :focus производит выбор элемента, который в настоящий момент находится в фокусе (допускается использовать на элементы, которые принимают события клавиатуры или другие данные, вводимые пользователем).

Поддержка браузерами

Селектор Chrome Firefox Opera Safari IExplorer Edge
:focus 4.0 2.0 9.6 3.1 8.0 12.0

CSS синтаксис:

Версия CSS

Пример использования

Пример использования псевдокласса :focus. CSS селекторы

Кажется, вы используете блокировщик рекламы :(

Этот ресурс не является коммерческим проектом и развивается на энтузиазме автора сайта, который посвящает все свое свободное время этому проекту.

Can I use :focus-within CSS pseudo-class?

Compatibility table for support of :focus-within CSS pseudo-class in desktop and mobile browsers.

Legend

  • Green = Supported
  • Red = Not supported
  • Greenish yellow = Partial support
  • Gray = Support unknown

:focus-within CSS pseudo- > — UNOFF

Global usage

The :focus-within pseudo-class matches elements that either themselves match :focus or that have descendants which match :focus .

  1. 5.5
  2. 6
  3. 7
  4. 8
  5. 9
  6. 10
  7. 11
  1. 12
  2. 13
  3. 14
  4. 15
  5. 16
  6. 17
  7. 18
  8. 76

Firefox

  1. 2
  2. 3
  3. 3.5
  4. 3.6
  5. 4
  6. 5
  7. 6
  8. 7
  9. 8
  10. 9
  11. 10
  12. 11
  13. 12
  14. 13
  15. 14
  16. 15
  17. 16
  18. 17
  19. 18
  20. 19
  21. 20
  22. 21
  23. 22
  24. 23
  25. 24
  26. 25
  27. 26
  28. 27
  29. 28
  30. 29
  31. 30
  32. 31
  33. 32
  34. 33
  35. 34
  36. 35
  37. 36
  38. 37
  39. 38
  40. 39
  41. 40
  42. 41
  43. 42
  44. 43
  45. 44
  46. 45
  47. 46
  48. 47
  49. 48
  50. 49
  51. 50
  52. 51
  53. 52
  54. 53
  55. 54
  56. 55
  57. 56
  58. 57
  59. 58
  60. 59
  61. 60
  62. 61
  63. 62
  64. 63
  65. 64
  66. 65
  67. 66
  68. 67
  69. 68
  70. 69
  71. 70
  72. 71
  73. 72

Chrome

  1. 4
  2. 5
  3. 6
  4. 7
  5. 8
  6. 9
  7. 10
  8. 11
  9. 12
  10. 13
  11. 14
  12. 15
  13. 16
  14. 17
  15. 18
  16. 19
  17. 20
  18. 21
  19. 22
  20. 23
  21. 24
  22. 25
  23. 26
  24. 27
  25. 28
  26. 29
  27. 30
  28. 31
  29. 32
  30. 33
  31. 34
  32. 35
  33. 36
  34. 37
  35. 38
  36. 39
  37. 40
  38. 41
  39. 42
  40. 43
  41. 44
  42. 45
  43. 46
  44. 47
  45. 48
  46. 49
  47. 50
  48. 51
  49. 52
  50. 53
  51. 54
  52. 55
  53. 56
  54. 57
  55. 58
  56. 59
  57. 60
  58. 61
  59. 62
  60. 63
  61. 64
  62. 65
  63. 66
  64. 67
  65. 68
  66. 69
  67. 70
  68. 71
  69. 72
  70. 73
  71. 74
  72. 75
  73. 76
  74. 77
  75. 78
  76. 79
  77. 80
  78. 81

Safari

  1. 3.1
  2. 3.2
  3. 4
  4. 5
  5. 5.1
  6. 6
  7. 6.1
  8. 7
  9. 7.1
  10. 8
  11. 9
  12. 9.1
  13. 10
  14. 10.1
  15. 11
  16. 11.1
  17. 12
  18. 12.1
  19. 13
  20. TP

Opera

  1. 9
  2. 9.5-9.6
  3. 10.0-10.1
  4. 10.5
  5. 10.6
  6. 11
  7. 11.1
  8. 11.5
  9. 11.6
  10. 12
  11. 12.1
  12. 15
  13. 16
  14. 17
  15. 18
  16. 19
  17. 20
  18. 21
  19. 22
  20. 23
  21. 24
  22. 25
  23. 26
  24. 27
  25. 28
  26. 29
  27. 30
  28. 31
  29. 32
  30. 33
  31. 34
  32. 35
  33. 36
  34. 37
  35. 38
  36. 39
  37. 40
  38. 41
  39. 42
  40. 43
  41. 44
  42. 45
  43. 46
  44. 47
  45. 48
  46. 49
  47. 50
  48. 51
  49. 52
  50. 53
  51. 54
  52. 55
  53. 56
  54. 57
  55. 58
  56. 60
  57. 62
  58. 63
  59. 64

iOS Safari

  1. 3.2
  2. 4.0-4.1
  3. 4.2-4.3
  4. 5.0-5.1
  5. 6.0-6.1
  6. 7.0-7.1
  7. 8
  8. 8.1-8.4
  9. 9.0-9.2
  10. 9.3
  11. 10.0-10.2
  12. 10.3
  13. 11.0-11.2
  14. 11.3-11.4
  15. 12.0-12.1
  16. 12.2-12.4
  17. 13.0-13.2

Opera Mini

Android Browser

  1. 2.1
  2. 2.2
  3. 2.3
  4. 3
  5. 4
  6. 4.1
  7. 4.2-4.3
  8. 4.4
  9. 4.4.3-4.4.4
  10. 76

Blackberry Browser

Opera Mobile

  1. 10
  2. 11
  3. 11.1
  4. 11.5
  5. 12
  6. 12.1
  7. 46

Chrome for Android

Firefox for Android

IE Mobile

UC Browser for Android

Samsung Internet

  1. 4
  2. 5.0-5.4
  3. 6.2-6.4
  4. 7.2-7.4
  5. 8.2
  6. 9.2
  7. 10.1

QQ Browser

Baidu Browser

KaiOS Browser

Browser support tables for modern web technologies

Created & maintained by @Fyrd, design by @Lensco.

Support data contributions by the GitHub community.

Usage share statistics by StatCounter GlobalStats for October, 2020

Использование: фокус для стилей внешнего div?

Когда я начинаю писать текст в текстовом поле, я хочу, чтобы внешний div, с полем класса, имел границу, которая стала твердой, а не пунктирной, но так или иначе фокус в этом случае не применяется. Если он работает с: активным, то как он не работает: focus?

Любые идеи, почему?

(Обратите внимание: я хочу, чтобы граница DIV стала твердой, а не текстовой)

Хотя этого не может быть достигнуто только с помощью CSS/HTML, это может быть достигнуто с помощью JavaScript (без библиотеки):

NB: Поддержка браузера: Chrome (60+), Firefox и Safari

Псевдокласс :focusCSS3-генератор ☛

Псевдокласс :focus определяет стиль для элемента, получающего фокус. Например, им может быть текстовое поле формы, в которое устанавливается курсор.

Синтаксис ?

Обозначения

Описание Пример
Указывает тип значения.
A && B Значения должны выводиться в указанном порядке. &&
A | B Указывает, что надо выбрать только одно значение из предложенных (A или B). normal | small-caps
A || B Каждое значение может использоваться самостоятельно или совместно с другими в произвольном порядке. width || count
[ ] Группирует значения. [ crop || cross ]
* Повторять ноль или больше раз. [, ]*
+ Повторять один или больше раз. +
? Указанный тип, слово или группа не является обязательным. inset?
Повторять не менее A, но не более B раз.
# Повторять один или больше раз через запятую. #
Пример

Примечание

Chrome не добавляет стиль для элемента a , чтобы заставить его понимать правило a:focus , добавьте к элементу атрибут tabindex .

Спецификация ?

Спецификация Статус
Selectors Level 4 Рабочий проект
Selectors Level 3 Рекомендация
CSS Level 2 (Revision 1) Рекомендация

Спецификация

Каждая спецификация проходит несколько стадий одобрения.

  • Recommendation ( Рекомендация ) — спецификация одобрена W3C и рекомендована как стандарт.
  • Cand >Возможная рекомендация ) — группа, отвечающая за стандарт, удовлетворена, как он соответствует своим целям, но требуется помощь сообщества разработчиков по реализации стандарта.
  • Proposed Recommendation ( Предлагаемая рекомендация ) — на этом этапе документ представлен на рассмотрение Консультативного совета W3C для окончательного утверждения.
  • Working Draft ( Рабочий проект ) — более зрелая версия черновика после обсуждения и внесения поправок для рассмотрения сообществом.
  • Editor’s draft ( Редакторский черновик ) — черновая версия стандарта после внесения правок редакторами проекта.
  • Draft ( Черновик спецификации ) — первая черновая версия стандарта.

Браузеры: Настольные Мобильные ?

Internet Explorer Chrome Opera Safari Firefox
8 1 7 1 1
Android Firefox Mobile Opera Mobile Safari Mobile
1 1 6 1

Браузеры

В таблице браузеров применяются следующие обозначения.

  • — элемент полностью поддерживается браузером;
  • — элемент браузером не воспринимается и игнорируется;
  • — при работе возможно появление различных ошибок, либо элемент поддерживается с оговорками.

Число указывает версию браузреа, начиная с которой элемент поддерживается.

Полное руководство по псевдоклассам и псевдоэлементам

Всем привет. В самом начале своей работы в веб-дизайне, я изучал все тяжелым способом: методом проб и ошибок. Тогда не было Smashing Magazine, Can I Use, CodePen и прочих волшебных вещей, окружающих нас сегодня. Если бы раньше кто-либо показал мне азы веб дизайна, особенно по части CSS, это было бы невероятно полезно.

Теперь я намного более опытен и хочу поделиться своим простым, понятным и не догматическим руководством по псевдоклассам и псевдоэлементам.

Если вы опытный веб-дизайнер или разработчик, то вы должны знать большинство обсуждаемых здесь псевдоклассов и псевдоэлементов. Однако я рекомендую вам ознакомиться с содержанием, возможно, вы встретите что-то незнакомое для себя.

Перед тем как погрузиться в вопрос, разберемся с терминами — если в названии есть псевдоклассы и псевдоэлементы, то что значит часть слова “псевдо”? Вот что говорит dictionary.com:

прилагательное 1. Ненастоящий, но похожий внешне; притворяющийся; ложный или мнимый 2. Почти такой же или пытающийся быть таким же

Не перегружаясь техническим определением W3C, псевдокласс можно определить, как фантомное состояние или специфическую характеристику элемента, которая может быть выделена с помощью CSS. Наиболее распространенные псевдоклассы это :link , :visited , :hover , :active , :first-child и :nth-child . Существуют и другие псевдоклассы, им мы тоже уделим внимание.

Псевдоклассы в стилях всегда выделяются предшествующим двоеточием ( : ), затем идет название псевдокласса и иногда значение в скобках.

Псевдоэлементы похожи на виртуальные элементы, которые мы можем обрабатывать как обычные HTML-элементы. Но они не существуют в дереве документа или в DOM, мы создаем их с помощью CSS.

Наиболее распространенные псевдоэлементы это :after , :before и :first-letter , мы рассмотрим их в конце статьи.

Одно или два двоеточия ставить перед псевдоэлементами?

Короткий ответ для большинства случаев — без разницы.

Двойное двоеточие ( :: ) было добавлено в CSS3, чтобы дифференцировать для различения псевдоэлементов типа ::before и ::after от псевдоклассов, таких как :hover и :active . Все браузеры поддерживают двойное двоеточие, кроме Internet Explorer (IE) 8 и ниже.

При этом некоторые псевдоэлементы, например, ::backdrop работают только с двойным двоеточием.

Лично я использую одно двоеточие ради совместимости с устаревшими браузерами, разумеется, кроме тех случаев, когда псевдоэлементам требуется двойное двоеточие.

Вы можете выбрать любой вариант, здесь нет однозначного “за” или “против”.

Однако спецификация на момент написания статьи рекомендует использовать одно двоеточие, по уже упомянутой здесь причине — обратной совместимости.

Не забывайте, что в CSS3 псевдоэлементы выделяются двойным двоеточием, типа a::after < … >, для их отличия от псевдоклассов. Вы можете иногда это видеть в CSS. При этом CSS3 также позволяет использовать одно двоеточие ради обратной совместимости и в настоящее время мы рекомендуем придерживаться этого синтаксиса.

В заголовках этой статьи, псевдоэлементы, поддерживающие оба синтаксиса будут показаны в обоих вариантах, а, соответственно, псевдоэлементы работающие только с двойным двоеточием будут показаны с ним.

Когда использовать и не использовать генерируемый контент в CSS

Генерируемый контент в CSS реализуется с помощью комбинации свойства content с псевдоэлементами :before или :after .

Контентом может быть простой текст или контейнер, которым мы манипулируем при помощи CSS, чтобы выводить графическую форму или декоративный элемент. Здесь я буду говорить о первом типе контента — тексте.

Генерируемый контент не стоит использовать для важного текста по следующим причинам:

  • Он будет недоступен скрин-ридерам;
  • Он будет невыделяем;
  • Если генерируемый контент использует излишнее содержание для украшения, скрин-ридеры будут читать его, что ухудшит впечатления пользователей.

Используйте генерируемый контент для декорации и незначительного текста, но убедитесь, что он правильно обрабатывается скрин-ридерами, чтобы использующие эту технологию не отвлекались на него. Основывайтесь на методике “прогрессивного улучшения”, когда собираетесь использовать генерируемый контент.

На Smashing Magazine есть отличная статья Габриеля Романато об использовании генерируемого контента.

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

Экспериментальными называют те псевдоклассы и псевдоэлементы, чья спецификация еще не стабильна и не окончательна. Их синтаксис и поведение еще могут измениться.

Однако мы можем использовать экспериментальные псевдоклассы и псевдоэлементы с помощью вендорных префиксов; о поддержке вы можете узнать с помощью Can I Use, а для удобства работы есть такие инструменты как -prefix-free или Autoprefixer.

В этой статье у всех экспериментальных псевдоклассов и псевдоэлементов будет соответствующая пометка.

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

Мы начнем с псевдоклассов для определенных состояний.

Псевдоклассы состояний

Псевдоклассы состояний обычно применяются после действий пользователя. При этом “действием” может считаться и отсутствие действия, например, в случае с непосещенной ссылкой.

Итак, рассмотрим их.

Псевдокласс :link представляет нормальное состояние ссылок и используется для выделения ссылок, которые до сих пор не посещены. В стилях рекомендуется объявлять этот псевдокласс перед всеми остальными классами этой категории. Полный порядок псевдоклассов такой: :link , :visited , :hover и :active .

Этот псевдокласс можно пропустить:

:visited

Псевдокласс :visited используется для стилизации ссылок, уже посещенных пользователем. В стилях он указывается вторым, после псевдокласса :link :

:hover

Псевдокласс :hover используется для стилизации элемента, на который в данный момент наведен курсор. Это может быть любой элемент, хотя применение этого псевдокласса для ссылок является самым распространенным случаем.

:active

Псевдокласс :active используется для стилизации “активированных” элементов, путем нажатия мыши или касания к экрану. Активация также может производиться и с клавиатуры, также как в случае с псевдоклассом :focus .

Он и работает аналогично :focus , с единственной разницей, что псевдокласс :active фиксирует событие между нажатием и отпусканием клавиши мыши.

Оно следует четвертым в стилях (после :hover ).

:focus

Псевдокласс :focus используется для стилизации элемента, получившего фокус с помощью курсора, касания или нажатия на клавиатуре. Он часто используется в элементах форм.

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

Если вы используете препроцессоры CSS, типа Sass, этот раздел должен заинтересовать вас. Если вы их не используете (не бойтесь, это нормально), вы можете пропустить его.

Итак, в духе оптимизации нашего рабочего процесса, ниже показан миксин Sass, позволяющий создать базовый набор ссылок.

Идея миксина состоит в отсутствии настроек по умолчанию в качестве аргументов, мы просто декларируем все 4 состояния ссылок.

Псевдоклассы :focus и :active обычно декларируются вместе, но при желании вы можете разделить их.

Учтите, этот миксин может быть применен к любому элементу HTML, не только к ссылкам. Вот он:

Структурные псевдоклассы

Структурные псевдоклассы направлены на дополнительные данные в дереве документа или DOM и не могут быть заменены другим типом селекторов или их комбинацией.

:first-child

Псевдокласс :first-child выделяет элемент, который является первым потомком своего родительского элемента.

В следующем примере только первый элемент li будет выделен оранжевым текстом.

:first-of-type

Псевдокласс :first-of-type выделяет первый элемент своего типа в указанном родительском контейнере.

В следующем примере первый элемент li и первый элемент span будут выделены оранжевым цветом.

:last-child

Псевдокласс :last-child выделяет элемент, которыя является последним дочерним элементом в родительском контейнере.

В следующем примере, последний элемент li будет выделен оранжевым цветом.

:last-of-type

Псевдокласс :last-of-type выделяет последний элемент своего типа в родительском контейнере.

В следующем примере, текст в последнем li и последнем span будет оранжевым.

Псевдокласс :not также известен как псевдокласс-отрицание. Он принимает в скобках аргумент — другой селектор. Этим аргументом может быть и другой псевдокласс. Аргументы могут составлять цепочку, но сам :not не может в этой цепочке передаваться в качестве аргумента.

В следующем примере, псевдокласс :not выберет все элементы, не подпадающее под селектор-аргумент. Оранжевым будет весь текст, кроме элемента li с классом .first-item :

Теперь попробуем сделать цепочку из двух псевдоклассов :not . У всех элементов будет черный цвет и желтый фон, кроме элемента li с классом .first-item и последнего li в списке.

Демо

:nth-child

Псевдокласс :nth-child выделяет один или более элементов в зависимости от их порядкового номера в разметке.

Это один из самых универсальных и надежных псевдоклассов в CSS.

Все псевдоклассы :nth принимают аргумент в виде формулы в скобках. Формула может быть просто целым числом, может структурироваться в виде an+b или использовать ключевое слово odd или even .

  • a это целое число;
  • n это литерал (т.е. мы просто используем букву n внутри формулы);
  • + это оператор (это может быть как + , так и — );
  • b это целое число, используемое только при использовании оператора.

Вот список с греческим алфавитом, на базе которого мы сделаем несколько примеров:

Выделим второй элемент в списке, только “Beta” будет оранжевой:

Теперь выделим все элементы с порядковыми номерами, кратными двум. Оранжевыми будут “Beta,” “Delta,” “Zeta,” “Theta” и “Kappa”:

Те же самые четные элементы можно выделить и с помощью ключевого слова even :

А теперь выберем все элементы кратные двум, начиная с шестого. Итак, оранжевыми будут “Zeta,” “Theta” и “Kappa”.

Демо

:nth-last-child

Псевдокласс :nth-last-child работает аналогично :nth-child , но выбирает элементы не с начала, а с конца.

Продолжим мучать греческий алфавит. Выберем второй элемент с конца — оранжевой у нас будет только “Iota”:

Теперь выберем все дочерние элементы по порядковому номеру с конца, кратному двум. Это будут Iota,” “Eta,” “Epsilon,” “Gamma” и “Alpha”:

Теперь выделим их же с помощью ключевого слова:

И, наконец. выберем все элементы с конца кратные двум начиная с шестого. “Epsilon,” “Gamma” и “Alpha”!

:nth-of-type

Псевдокласс :nth-of-type схож с :nth-child с той разницей, что он обладает большей специфичностью, так как выбирает конкретный тип элемента внутри родительского контейнера.

В следующем примере, оранжевый цвет будет у второго параграфа.

:nth-last-of-type

Псевдокласс :nth-last-of-type делает то же, что и :nth-of-type , но отсчитывая с конца.

В следующем примере мы будем выбирать второй параграф с конца (это будет первый параграф в статье):

Дополнительные ресурсы по классам семейства :nth

:only-child

Псевдокласс :only-child выбирает единственного потомка родительского элемента.

В следующем примере, в первом ul есть только один элемент, который будет выделен оранжевым. В следующем ul несколько потомков, поэтому их этот селектор не затронет.

:only-of-type

Псевдокласс :only-of-type выбирает элемент, у которого нет соседних элементов того же типа. Он похож на :only-child , но более осмыслен за счет указания конкретного элемента.

В следующем примере в первом ul только один элемент списка, который и будет выделен оранжевым.

:target

Псевдокласс :target выбирает элемент, ID которого используется в качестве хэша в URL.

В следующем примере, статья с ID target будет выделяться, когда URL в адресной строке будет завершаться на #target .

URL: http://awesomebook.com/#target

Совет: короткая запись background в стилях успешно заменяет background-color .

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

Формы всегда были ядом веб-дизайна и веб-разработки. С помощью псевдоклассов валидации, мы можем сделать процесс заполнения форм более плавным и приятным.

Заметьте, что несмотря на то, что большинство псевдоклассов этого раздела работают с элементами форм, некоторые из них могут работать и с другими элементами HTML.

:checked

Псевдокласс :checked выбирает радиокнопки, чекбоксы и опции, которые были отмечены пользователем.

В следующем примере, при выделении пользователем чекбокса, его метка подсвечивается, что улучшает интерфейс.

Демо

:default

Псевдокласс :default выбирает элемент, заданный в качестве дефолтного в группе похожих элементов.

В случае, если вам надо выбрать кнопку по умолчанию в форме с незаданным классом, вы можете использовать псевдокласс :default .

Учитывайте, что наличие кнопки “Reset” или “Clear” в форме создает проблемы с юзабилити. Подробнее об этом можно прочитать в следующих статьях.

Демо

:disabled

Псевдокласс :disabled выбирает отключенный элемент формы (элемент, который пользователь не может выделить, отметить, активировать или перенести на него фокус).

В следующем примере поле ввода name , поэтому оно будет выведено наполовину прозрачным.

Совет: в разметке не обязательно писать disabled=»disabled» , того же результата можно достичь просто использовав атрибут disabled . Однако полная запись необходима в XHTML.

Демо:

:empty

Псевдокласс :empty выбирает элементы, в которых нет никакого содержимого. Если в элемент есть другой элемент HTML, символ или пробел, элемент не считается пустым.

Вот более полные определения:

Нет содержимого или каких-либо символов. Комментарии HTML содержимым не считаются.

Не пустой элемент

В элементе есть какие-либо символы, даже невидимые, например, пробел.

В следующем примере:

  • В верхнем контейнере есть текст, поэтому у него будет оранжевый фон;
  • Во втором контейнере есть пробел, который считается контентом, его фон также будет оранжевым;
  • В третьем контейнере нет ничего — он пустой и поэтому у него желтый фон.
  • В последнем контейнере есть комментарий HTML, который не считается контентом и поэтому у контейнера желтый фон.

Демо:

:enabled

Псевдокласс :enabled выбирает элементы, включенные для пользователя; по умолчанию все элементы формы включены, если в разметке им не задан атрибут disabled .

Мы можем использовать комбинацию :enabled и :disabled , чтобы обеспечить визуальную обратную связь, улучшая тем самым пользовательский опыт.

В следующем примере, ранее отключенное поле ввода name включено, к нему добавлена однопиксельная граница зеленого цвета и полная непрозрачность.

Совет: использование в разметке enabled=»enabled» не требуется, достаточно просто enabled ; исключением является только XHTML.

Демо:

:in-range

Псевдокласс :in-range выбирает элементы, которым задан диапазон и значение, которых входит в этот диапазон.

В следующем примере поле ввода поддерживает диапазон между 5 и 10, все значения между ними вызовут измение цвета границы поля на зеленый.

Демо:

:out-of-range

Псевдокласс :out-of-range выбирает элемент, у которого есть диапазон и значение которого не входит в этот диапазон

В следующем примере поле ввода поддерживает диапазон от 1 до 12 — для всех остальных значений будет задан оранжевый цвет границы поля.

Демо:

:indeterminate

Псевдокласс :indeterminate выбирает элементы ввода типа радиокнопок и чекбоксов, которые не выделены или выделение которых снято после загрузки страницы.

Образцом этого можно назвать загрузку страницы с радиокнопками, ни одна из которых не выбрана по умолчанию или ситуацию, когда свойство indeterminate задается чекбоксу с помощью JavaScript.

Демо:

:valid

Псевдокласс :valid выбирает элемент формы, если она заполнена корректно в соответствии с требуемым форматом.

В следующем примере поле ввода email отформатировано правильно, поэтому оно будет считаться валидным и, соответственно, получит однопиксельную зеленую границу.

:invalid

Псевдокласс :invalid выбирает элемент формы, если она заполнена некорректно в соответствии с требуемым форматом.

В следующем примере, поле ввода email отформатировано неправильно, поэтому оно будет считаться невалидным и, соответственно, получит однопиксельную оранжевую границу.

Демо:

:optional

Псевдокласс :optional выбирает поля ввода, которые не являются обязательными. Другими словами, любой элемент input без атрибута required будет выбран псевдоклассом :optional .

В следующем примере поле ввода опционально — у него нет атрибута required и поэтому текст в этом поле будет серым.

:read-only

Псевдокласс :read-only выбирает элемент, которые не может быть отредактирован пользователем. Он похож на :disabled — и выбор между ними зависит от использованного атрибута в разметке.

Этот псевдокласс может быть полезен, например, в форме с предварительно заполненной информацией, которую нельзя изменить, но которую надо показать пользователю.

В следующем примере у элемента input есть атрибут readonly . Мы выделим этот элемент серым цветом благодаря псевдоклассу :read-only .

Демо:

:read-write

Псевдокласс :read-write выбирает элементы, которые могут редактироваться пользователем. Он может работать со всеми элементами HTML с атрибутом contenteditable .

Этот псевдокласс можно сочетать с псевдоклассом :focus для улучшения пользовательского опыта в определенных ситуациях.

В следующем примере, пользователь может после щелчка мышью редактировать содержимое элемента div . Мы облегчим пользователю понимание этого, добавив стили, отличающие редактируемую часть контента от всего остального.

Демо:

:required

Псевдокласс :required выбирает поля ввода, которым задан атрибут required .

В дополнение к традиционному астериску (*), которым обычно отмечают обязательные поля, мы можем добавить стили CSS, таким образом мы берем лучшее из двух миров.

В следующем примере, у поля ввода есть атрибут required . Мы можем улучшить впечатления пользователя, соответствующим стилем показав обязательность поля.

Демо:

:scope (эксп.)

Псевдокласс :scope имеет смысл, когда он привязан к HTML-атрибуту scoped тега style .

Если этого атрибута у тега style нет в разделе страницы, значит этот псевдокласс выберет элемент html , который является зоной видимости для стилей по умолчанию.

В следующем примере, у блока HTML есть стили с атрибутом scoped , поэтому весь текст второго элемента section будет выделен курсивом.

Демо:

Псевдоклассы, связанные с языком страницы

Языковые псевдоклассы связаны с текстом, содержащимся на странице. Они не работают с медиа-контентом типа изображений или видео.

:dir (эксп.)

Псевдокласс :dir выбирает элемент, направленность текста в котором определена в документе. Другими словами, чтобы использовать этот псевдокласс, нам надо в разметке у соответствующего элемента добавить атрибут dir .

На данный момент поддерживается два направления текста: ltr (слева направо) и rtl (справа налево).

На момент написания статьи только Firefox (с префиксом -moz-dir() ) поддерживается псевдокласс :dir . В будущем префикс, скорее всего, будет не нужен, поэтому в примерах селектор задан как с префиксом, так и без него.

Примечание: Сочетание префиксной и безпрефиксной версий в одном правиле не работает. Надо создавать два отдельных правила.

В следующем примере оранжевым цветом будет выделен параграф на арабском (как известно, текст в нем пишется справа налево).

В англоязычном параграфе (слева направо) текст будет синим.

Демо:

Псевдокласс :lang выбирает элемент с указанным языком. Язык может быть задан с помощью атрибута lang=»» , соответствующего элемента meta или же в HTTP-заголовках.

Атрибут lang=»» обычно используется с тегом html , но он также может применяться и к любому другому тегу.

Для чего этом можно использовать? Например, общей практикой является использование традиционных для каждого языка кавычек с помощью свойства CSS quotes . Однако большинство браузеров (включая IE9 и выше) способны добавлять нужные кавычки автоматически, если они не объявлены в CSS.

В зависимости от обстоятельств, это может помогать или мешать, так как есть разница между кавычками, автоматически добавляемыми браузером по умолчанию и обычно используемыми кавычками, добавленными в CSS.

Вот, например, немецкие кавычки, добавленные браузером:

Однако, в большинстве случаев, немецкие кавычки добавленные в CSS выглядят так:

Верными являются оба варианта. Поэтому решение остается за вами — отдать ли выбор кавычек на усмотрение браузера или использовать псевдокласс :lang и свойство CSS quotes .

Давайте добавим кавычки с помощью CSS.

Демо:

Остальные псевдоклассы

Теперь перейдем к оставшемся псевдоклассам и их функциональности

Псевдокласс :root ссылается на высший родительский элемент в документе.

Виртуально во всех случаях в роли :root будет элемент html . Однако это может быть и другой элемент, если используется другой язык разметки, такой как SVG или XML.

Давайте добавим фоновый цвет к элементу html .

Примечание: мы можем добиться того же эффекта, использовав в качестве селектора html . Но так как :root псевдокласс у него большая специфичность, чем у селектора элемента.

:fullscreen (эксп.)

Псевдоклассс :fullscreen выбирает элемент, выведенный на всю ширину экрана.

Однако, он не рассчитан на работу при нажатии пользователем F11 и переходе браузера в полноэкранный режим. Он скорее ориентирован на работу с JavaScript Fullscreen API, предназначенном для изображений, видео и игр, выполняющихся в родительском контейнере.

О переходе в полноэкранный режим выводится сообщение в верхней части браузера, вернуться из него можно нажав клавишу Escape . Мы сталкиваемся с этим при просмотре видео в максимальном размере на YouTube или Vimeo.

Если вы собираетесь использовать псевдокласс :fullscreen , учитывайте, что стили браузеров в этом режиме очень различны. И вам придется использвать браузерные префиксы не только в CSS, но и в JavaScript. Я рекомендую использовать библиотеку Эрнан Райчерта screenfull.js, решающую большую часть проблем с кроссбраузерными глюками.

Рассмотрение Fullscreen API находится за пределами этой статьи, вот сниппет, который будет работать в браузерах на движках WebKit и Blink.

Демо:

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

Как упоминалось в начале статьи, псевдоэлементы можно сравнить с виртуальными элементами, которые можно обрабатывать как обычные элементы HTML. Они не существуют в дереве документа или в DOM, это значит, что мы их создаем с помощью CSS.

Также напомню, что разница между двойным и одиночным доветочиями это просто визуальное различие между псевдоэлементами стандартов CSS 2.1 и CSS3, вы можете свободно использовать любой вариант.

::before/:before

Псевдоэлемент :before , также как и его сосед :after добавляет содержимое (текст или форму) к другому элементу HTML. Еще раз отмечу, что этого контента нет в DOM, но им можно манипулировать, как будто он есть. Свойство content надо добавлять в CSS.

Запомните, что добавленный в псевдоэлемент текст нельзя выделить.

В результате будет выведено:

Примечание: Обратили внимание на пробел после “Hello ”? Да, о пробелах надо позаботиться самостоятельно.

::after/:after

Псевдоэлемент :after также используется для добавления содержимого (текста или формы) к другому элементу HTML. Этот контент отсутствует в DOM, но им можно манипулировать, как будто он есть; свойство content надо добавлять в CSS. Текст, добавленный в псевдоэлемент, нельзя выделить.

В результате будет выведено:

::backdrop (эксп.)

Псевдоэлемент ::backdrop это бокс, генерируемый перед полноэкранным элементом, расположенным над всем остальным контентом. Он используется в сочетании с псевдоклассом :fullscreen для изменения цвета фона максимизированного окна — если вас не устраивает дефолтный черный.

Примечание: для псевдоэлемента ::backdrop обязательно двойное двоеточие, иначе он не работает.

Разовьем наш пример с псевдоклассом :fullscreen :

Демо:

::first-letter/:first-letter

Псевдоэлемент :first-letter выбирает первый символ на строке текста. Если перед текстом есть элемент типа изображения, видео или таблицы, он не влияет на текст и первая буква по-прежнему выбирается из текста.

Это отличная вещь для использования в параграфах, для повышения типографской привлекательности без использования изображений и внешних ресурсов.

Совет: этот псевдоэлемент способен захватывать первую букву, сгенерированного контента в :before , несмотря на его отсутствие в DOM.

::first-line/:first-line

Псевдоэлемент :first-line выбирает первую строку в элементе. Он не работает со строчными элементами, только с блочными.

При использовании в параграфе, например, только первая строка будет стилизована, даже если текст обтекает другой элемент.

::selection

Псевдоэлемент ::selection используется для стилизации выделенного текста. Браузеры на движке Gecko пока используют версию с префиксом ::-moz-selection .

Примечание: сочетание в одном правиле синтаксиса с префиксом и без префикса не работает, надо создавать два отдельных правила.

::placeholder (эксп.)

Псевдоэлемент ::placeholder выбирает текст, добавленный в качестве заглушки в элементы формы с помощью атрибута placeholder .

Его также можно указывать как ::input-placeholder , этот синтаксис фактически и используется в CSS.

Примечание: этот элемент еще не является частью стандарта, с большой вероятностью его имплементация изменится в будущем, поэтому используйте его с осторожностью.

В некоторых браузерах (IE 10 и Firefox до версии 18), псевдоэлемент ::placeholder реализован как псевдокласс, но во всех остальных браузерах это псевдоэлемент, поэтому если вы не поддерживаете старые версии Firefox и IE 10, вы будете писать примерно такой код:

Заключение

Итак, похоже, это все.

Псевдоклассы и псевдоэлементы CSS однозначно удобны, не так ли? Они дают такое количество возможностей, что вы чувствуете себя перегруженными. Но в этом все жизнь веб-дизайнеров и разработчиков.

Тщательно тестируйте код. Хорошо реализованные псевдоклассы и псевдоэлементы должны пройти долгий путь.

Состояния ссылок в CSS. Псевдоклассы

Первый урок четвертой главы мы начнем с изучения ссылок, а точнее, будем разбираться с тем, какие состояния бывают у ссылки, и как через CSS можно повлиять на ее вид в том или ином состоянии, используя соответствующие псевдоклассы.

Какими бывают состояния ссылок

Взаимодействия пользователя с элементами веб-страницы отслеживаются браузером. Если говорить о ссылках, им присваивается определенный статус в зависимости от того, какое действие было совершено (наведение, нажатие, переход по ссылке и т. д.). Это мы и называем состояниями ссылок.

Когда вы пишете стиль CSS, то с помощью селектора указываете, для какого элемента он предназначен. В самом начале учебника, когда мы изучали селекторы, в одном из уроков рассматривались псевдоклассы CSS, благодаря которым можно задавать стили для разных состояний элемента, в том числе для ссылок. Ниже — четыре состояния, которые могут принимать ссылки:

  • :hover — ссылка, на которую наведен курсор;
  • :active — активная ссылка (та, по которой совершается клик, или на которой удерживается кнопка мыши);
  • :link — ссылка, еще не посещенная пользователем;
  • :visited — посещенная ссылка.

Для справки: из соображений безопасности набор стилей, которые можно использовать для ссылок :visited , ограничен. Посещенные ссылки принимают только свойства color , background-color , border-color (и его производные), column-rule-color , outline-color . При этом свойство к посещенной ссылке можно применить, только если это же свойство задано и для обычной. Прозрачность цвета, установленная через альфа-канал для элемента :visited , будет проигнорирована. JavaScript-метод getComputedStyle всегда возвращает значение цвета непосещенных ссылок, даже если у посещенных ссылок цвет иной.

Стилизация состояний

С помощью псевдокласса :hover можно существенно изменить стиль ссылки, которая находится в состоянии наведенного на нее курсора. Простейший пример:

Псевдокласс :active также поддается гибкой стилизации:

Если в ваши планы входит максимально детальная проработка дизайна ссылок, то желательно определить стили для всех четырех состояний. При этом очень важно соблюсти порядок, в котором будут записаны селекторы с псевдоклассами. Обязательно размещайте их в следующей последовательности:

Что будет, если поменять строки местами? В этом случае некоторые стили перестанут работать согласно правилам каскадности. Дело в том, что ссылка может находиться одновременно в двух состояниях, к примеру, в :visited и в :hover , и если расположить стиль для :hover выше, чем стиль для :visited , то первый перекроется.

Выбор ссылок с помощью селекторов

Как записать селектор с псевдоклассом для определенной группы ссылок? Например, если вам нужно применить какой-то стиль для всех ссылок навигационного меню с идентификатором #main-menu , когда такая ссылка находится в состоянии наведенного на нее курсора, вы можете использовать такой селектор:

Либо, если у каждой ссылки этого меню дополнительно имеется свой класс (допустим, это .menu-link ), то такая запись тоже подойдет:

Чтобы определить стили для всех состояний данных ссылок, запишите для каждого псевдокласса отдельное правило:

Обширные возможности CSS в плане построения селекторов позволяют с удобством делать точную выборку ссылок, которые вам необходимо стилизовать. А какие именно свойства CSS применимы к ссылкам, мы обсудим в следующем уроке.

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

Псевдоклассы используются для добавления специальных эффектов для некоторых селекторов. Чтобы применить эти эффекты, не нужно использовать JavaScript или любой другой скрипт.

Простой синтаксис псевдоклассов выглядит следующим образом:

Классы CSS также могут использоваться с псевдоклассами:

Наиболее часто используемые CSS псевдоклассы:

Значение Описание
:link Класс открывавшейся ранее ссылки.
:visited Класс открытой ранее ссылки.
:hover Класс элемента, когда на него наведен курсор мыши.
:active Класс для активного элемента.
:focus Класс для элемента, который находится в фокусе.
:first-child Класс элемента, который является дочерним элементом другого.
:lang Класс, чтобы указать язык, применяемый для конкретного элемента.

При определении псевдоклассов CSS3 в блоке следует помнить:

  • a:hover должен располагаться после a:link и a:visited , иначе он не будет работать;
  • a:active должен располагаться после a:hover , иначе он не будет работать;
  • Имена псевдоклассов не чувствительны к регистру;
  • Псевдоклассы отличаются от классов CSS , но они могут быть объединены.

В следующем примере показано, как использовать псевдокласс ссылки, чтобы задать цвет ссылки. Возможные значения — цвет в любом допустимом формате:

Этот код создает следующую черную ссылку:

Псевдокласс :visited

Ниже приведен пример того, как использовать псевдокласс HTML :visited , чтобы задать цвет открытой ранее ссылки. Возможные значения — цвет в любом допустимом формате:

Этот код создает следующую ссылку. После того, как вы нажмете на нее, она изменит свой цвет на зеленый:

Псевдокласс :hover

В следующем примере показано, как использовать псевдокласс hover , чтобы изменить цвет ссылки при наведении на нее курсора мыши. Возможные значения — цвет в любом допустимом формате:

Этот код создает следующую ссылку. Теперь наведите курсор мыши на эту ссылку, и вы увидите, что она поменяет свой цвет на желтый:

Псевдокласс :active

В следующем примере показано, как использовать класс :active , чтобы изменить цвет активной ссылки. Можно использовать значение цвета в любом допустимом формате:

Этот код создает следующую ссылку. Когда пользователь нажимает на нее, цвет меняется на розовый:

Псевдокласс :focus

В следующем примере показано, как использовать псевдокласс focus , чтобы изменить цвет ссылки, находящейся в фокусе ввода. Возможные значения — цвет в любом допустимом формате:

Этот код создает следующую ссылку. Когда эта ссылка находится в фокусе ввода, ее цвет меняется на оранжевый. Цвет возвращается обратно, когда ссылка находится вне фокуса:

Псевдокласс :first-child

Псевдокласс child задается указанному элементу, который является дочерним элементом другого.

Чтобы :first-child работал в IE должен объявляться в верхней части документа.

Например, для создания отступа для первого абзаца всех элементов

Этот код дает следующий результат:

Псевдокласс :lang

Псевдокласс :lang позволяет составлять селекторы для отдельных тегов на основе настроек языка.

Этот класс полезен при создании документов, которые должны содержать текст на нескольких языках, имеющих различные конвенции для некоторых языковых конструкций. Например, во французском языке для обозначения цитаты, как правило, используются угловые скобки ( ), в то время как в английском языке используются одинарные кавычки (‘ and ‘).

В таком документе вы можете использовать псевдокласс :lang , чтобы изменить кавычки надлежащим образом. Приведенный ниже код изменяет тег

надлежащим образом для каждого языка:

Селекторы :lang будут применяться ко всем элементам в документе. Но не все элементы используют свойство quotes , так что для большинства элементов эффект будет незаметен.

Этот код дает следующий результат:

Данная публикация представляет собой перевод статьи « CSS — Pseudo Classes » , подготовленной дружной командой проекта Интернет-технологии.ру

Добавляем в Chromium селектор :focus-within

В этой статье рассказывается о внедрении в Chromium/Blink новой фичи. А именно — псевдокласса :focus-within из спецификации Selectors 4. Также поговорим о разных вещах, с которыми приходится сталкиваться при разработке.

Псевдокласс :focus-within

Это новый селектор, позволяющий модифицировать стиль элемента при фокусировке на этом элементе или любом из его дочерних элементов (descendant). Это аналогично действию селектора :focus , только применяется и по отношению к родительским элементам, так что работает примерно как :active и :hover .

Всё будет понятно из примера:

Когда пользователь выбирает форму ввода, её фон становится зелёным.

Намерение поставки

Хотя спецификация всё ещё в состоянии Editor’s Draft (редакторский черновик), она уже реализована в Firefox 52 и Safari 10.1, так что она хороший кандидат и на добавление в Chromium.

Для этого вам нужно отправить письмо о намерении в blink-dev. Задача казалась простой и лёгкой, и после небольшого раздумья я отправил письмо Intent to Implement and Ship: CSS Selectors Level 4: :focus-within pseudo-class (Намерение о внедрении: CSS Selectors Level 4: псевдокласс :focus-within).

Но тут возникло первое затруднение…

Проблемы со спецификацией

На первый взгляд кажется, что фича очень простая. Но Web Platform — вещь сложная, с большим количеством внутренних взаимосвязей.

В моём случае удалось быстро выявить проблему с текстом спецификации, связанную с использованием этого селектора (а также :active и :hover ) с Shadow DOM. Старый текст спецификации гласит:

Элемент также соответствует (matches) :focus-within , если один из его дочерних элементов, включающий в себя Shadow, соответствует :focus .

Похоже, спецификация готова в отношении Shadow DOM, но в ней есть ошибка. Это может быть не так просто понять, но, если интересно, взгляните на пример:

Если не поняли: элемент input вставляется в тег slot (быстрое и упрощённое объяснение этого конкретного примера с Shadow DOM).
В этом примере flat tree будет выглядеть так:

Проблема в том, что когда фокусируешься на input, который сейчас внутри slot , то ожидаешь, что рамка вокруг shadowDiv станет зелёной. Однако input не является дочерним элементом shadowDiv, включающим в себя Shadow. Вместо этого в спецификации должно говориться о дочерних элементах flat tree.

О проблеме было сообщено в GitHub-репозитории CSS WG, в спецификации теперь говорится:

Элемент также соответствует (matches) :focus-within , если один из его дочерних элементов в flat tree (включающий неэлементные узлы (non-element nodes) вроде текстовых) соответствует условиям соответствия :focus .

Внедрение :focus-within

После решения проблемы со спецификацией намерение было одобрено. Моему внедрению дали зелёный свет.

Патч, добавляющий поддержку фичи, в основном состоит из шаблонного кода (boilerplate code), необходимого для добавления в Blink нового селектора. По большей части он делает всё то же самое, что и :focus , но затем идёт интересная часть: циклический проход по дочерним элементам с помощью flat tree:

Что насчёт тестов?

Конечно, любые изменения в Blink нужно протестировать. Мне повезло, в репозитории W3C Web Platform Tests (WPT) уже было несколько тестов для этого нового селектора.

Я импортировал тесты (не без проблем) в Blink и проверил, что мой патч их проходит (включая тесты Mozilla, которые уже апстримлены). Также я прошерстил тесты в репозитории WebKit, поскольку они уже внедрили эту фичу, и апстримил один из них, проверявший некоторые интересные комбинации. Наконец, я написал ещё несколько тестов для покрытия дополнительных ситуаций (вроде описанной выше проблемы со спецификацией).

Фокус и display:none

Во время code review мне помогли найти ещё один спорный момент. Что произойдёт с выбранным элементом, когда он помечен как display: none ? На первый взгляд кажется, что фокусировка должна быть снята, и это действительно так (в спецификации HTML есть правило, описывающее такую ситуацию).

Но здесь идёт речь о проблеме совместимости, потому что это правило в Blink соблюдается только движком. Применительно к остальным браузерам опубликованы отчёты о багах, то есть о проблеме, судя по всему, известно. Однако она пока никак не решена. Вот один из отчётов: Chromium bug #491828.

Если воспользоваться селектором :focus для изменения, например, цвета фона в input, то не особенно важно, что происходит, когда этот input получает display: none и исчезает. Какая разница, что делается с фоном того, что вы больше не видите. Но в случае с focus-within эта проблема более важна. Представьте, что вы изменили цвет фона в форме, когда выбрано какое-то из полей ввода. Если оно помечено как display: none , то не будет фокусировки ни на одном из полей формы, а цвет фона должен быть изменён. Но сейчас это происходит только в Chromium.

Стратегия работы с родительским элементом

Изначально патч с поддержкой :focus-within внедрили в Chrome 59, но пометили флагом как экспериментальный. Основная причина: его ещё нужно доработать, чтобы он был включён по умолчанию.

Одна из доработок была связана с повторными вычислениями стилей (style recalculations). Начальная реализация приводила к избыточному количеству вычислений.

Возьмём новый пример:

Что произойдёт, когда вместо input1 вы выберете input2 ?

Рассмотрим пошагово, как это работает в первоначальном патче:

  1. Сначала выбирается input1 , так что этот элемент и все его дочерние элементы — в том числе input1 , li1 , ul и form (на самом деле даже body и html , но здесь мы их опустим) — получают флаг :focus-within (у всех появляется зелёная рамка).
  2. Потом переходим на input2 . Первый выбранный элемент — input1 — теряет фокусировку. И здесь мы проходим по цепочке родительских элементов, убирая флаг :focus-within у input1 , li1 , ul и form .
  3. Теперь input2 действительно выбран. Снова идём по цепочке родительских элементов и добавляем флаг у input2 , li2 , ul и form .

Мы убрали и добавили флаг у элементов form и ul , хотя это была избыточная операция, ведь в результате они пришли к тому же состоянию.

В новой версии патча в пункт 2 внесли изменение: теперь у элементов, теряющих и получающих фокусировку, ищутся общие родительские элементы. В нашем случае при переходе с input1 к input2 это будет ul . Проходя по цепочке родительских элементов для добавления/удаления флага :focus-within , система пропускает общий родительский элемент и оставляет его (и всех его родителей) неизменённым. Так мы экономим количество вычислений.

Теперь в пункте 2 флаг будет снят только у input1 и li1 , а в пункте 3 добавится только у input2 и li2 . Элементы ul и form останутся нетронутыми.

И дополнительно…

Закончив работу в Chromium, я сообразил, что WebKit не соблюдает спецификацию в случае с flat tree. Поэтому я импортировал в WebKit тесты WPT и написал патч, позволяющий использовать flat tree и в WebKit.

Добавление нового селектора может выглядеть простой задачей. Но позвольте показать вам количество коммитов в разные репозитории, которые были связаны с этой работой:

И будут ещё коммиты, потому что я делаю новые модификации тестов, чтобы можно было без проблем использовать их в Blink и WebKit.

Применение

Теперь всё готово, :focus-within будет доступен по умолчанию в Chrome 60. Можно его использовать.

Я написал простую демку, показывающую, что позволяет сделать новая фича. Но вы сможете придумать куда более интересные варианты.

Новый селектор важен для повышения доступности веб-приложений и сайтов, особенно при работе с клавиатурой. Например, если у вас задействован только :hover , то часть пользователей, которые привыкли к кнопочной навигации, не смогут воспользоваться вашим продуктом. А если вы добавите :focus-within — вы избежите таких проблем.

Я создал типичное меню, использующее :hover и :focus-within, взгляните, как теперь работает кнопочная навигация.

Обратите внимание, что в Firefox есть баг, из-за которого этот пример не работает.

Илон Маск рекомендует:  Мобильные устройства и оптимизация производительности
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL