CSS: после того, как не добавили контент в определенные элементы

100

Мне сложно понять поведение :afterсвойства CSS . Согласно спецификации ( здесь и здесь ):

Как показывают их имена, псевдоэлементы :beforeи :afterопределяют расположение содержимого до и после содержимого дерева документа элемента.

Это, похоже, не накладывает ограничений на то, какие элементы могут иметь свойство :after(или :before). Однако, похоже, он работает только с определенными элементами ... <p>работает, <img>не <input>работает, не <table>работает. Я мог бы проверить больше, но суть ясна. Обратите внимание, что это выглядит одинаково во всех браузерах. Что определяет , может ли объект принять :beforeи :afterнедвижимость?

Эйканал
источник

Ответы:

157

imgи inputоба являются заменяемыми элементами .

Заменяемый элемент - это любой элемент, внешний вид и размеры которого определяются внешним ресурсом. Примеры включают в себя изображения ( <img>теги), плагин ( <object>тэги), а также элементы формы ( <button>, <textarea>, <input>, и <select>метка). Все остальные типы элементов могут называться незамещенными элементами.

:beforeи :afterработать только с незаменяемыми элементами.

Из спецификации :

Заметка. Данная спецификация не полностью определяет взаимодействие :beforeи :afterс замененными элементами (например, IMG в HTML). Это будет определено более подробно в будущих спецификациях.

С span:before, span:afterDOM выглядит так:

<span><before></before>Content of span<after></after></span>

Очевидно, это не сработает <img src="" />.

тридцать точек
источник
2
«Созданный контент не изменяет дерево документа». Поэтому я был бы удивлен, если бы вы смогли найти в источнике что-то вроде " <before></before>".
Knu 04
4
@Knu: Ты прав, я плохо объяснил. Вы никогда не найдете <before></before>. Я должен был сказать «притвориться DOM» или что-то в этом роде. Смысл в том, чтобы показать, что :beforeи :afterнаходятся внутри элемента, а не вне его.
30dot 04
Нет, они не хранятся в теневом DOM.
инструмент
3
Приведенная спецификация не говорит об этом :beforeи :afterне работает для замененных элементов; он просто говорит, что не «полностью определяет», как и что это будет определено в будущем (чего еще не произошло). То, что происходит в DOM, здесь не имеет значения. Хотя браузеры не поддерживают поддержку этих псевдоэлементов для некоторых элементов, это не входит в спецификации, а только то, что делают реализации.
Юкка К. Корпела
Раньше я считал логичным объяснение, что ::beforeи ::afterне работают для пустых (пустых) элементов, которые никогда не имеют фактического содержимого, до / после которого они могут применяться. Но, что удивительно, они работают с hrelement почти во всех браузерах.
Илья Стрельцын
9

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

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

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

Совершенно неясно, что означает «замененный элемент», и значение, похоже, несколько изменилось. Он часто интерпретируется как означающий то же, что и пустой элемент (элемент с EMPTYобъявленным содержимым, то есть элемент, который не может иметь никакого содержимого), но сам CSS 2.1 показывает образец таблицы стилей с селектором br:before(хотя браузеры проигнорировали это, реализовав brсвои собственные путь). Можно утверждать, что все больше и больше элементов, по крайней мере частично, переходят в сферу рендеринга CSS. Например, inputэлемент (включая его шрифт, цвета и т. Д.) В значительной степени контролируется с помощью CSS в современных браузерах.

Современные браузеры (Firefox, IE, Chrome) , кажется, не поддерживают :afterи :beforeпсевдо-элементы для других , чем пустых элементов hr. Для получения hr, IE и хром разместить сгенерированный контент внутри окаймленной коробки, которая является реализацией hr; содержимое делает коробку выше. Firefox помещает содержимое обоих (!) Псевдоэлементов после горизонтального правила, которое является его реализацией hr. Этот вариант иллюстрирует типы проблем «взаимодействия», которые упоминаются в CSS 2.1.

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

В заключение, :afterи :beforeв настоящее время не могут использоваться для пустых элементов (за исключением незначительного hr), но это в основном связано с реализациями и может измениться в будущем.

Юкка К. Корпела
источник
-1

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

https://www.w3.org/TR/html5/syntax.html#void-elements

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

Вот пример: https://codepen.io/equinusocio/pen/BOBaEM/

input[type="checkbox"] {
  appearance: none;
  color: #000;
  width: 42px;
  height: 24px;
  border: 1px solid currentColor;
  border-radius: 100px;
  cursor: pointer;
  transition: all 100ms;
  background-size: 30%;
  outline: none;
  position: relative;
  box-sizing: border-box;
  background-color: #eee;
  transition: background-color 200ms;

  &::before {
    content: '';
    position: absolute;
    left: 2px;
    top: 2px;
    bottom: 2px;
    height: 18px;
    width: 18px;
    border-radius: 50%;
    background-color: currentColor;
    will-change: transform;
    transition: transform 200ms cubic-bezier(.01,.65,.23,1);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
  }

  &:checked {
    background-color: aquamarine;

    &::before {
      transform: translateX(100%);
    }
  }
}
Маттиа Асторино
источник
он не будет работать во всех браузерах ... и нет спецификации, в которой говорится, что теперь мы можем ... если он у вас есть, поделитесь им, потому что небезопасно рассматривать псевдоэлемент с вводом
Темани Афиф
Работает во всех браузерах, кроме IE. Даже flexbox не поддерживается IE 9, так что в чем проблема. Это решение работает во всех браузерах Blink, Webkit и Quantum и может быть очень полезным для людей, которые работают в среде только для webkit, такой как Electron.
Маттиа Асторино
Как вы сказали в своем ответе, для него нет спецификации, поэтому однажды он может перестать работать. Это не единственное, что ведет себя и работает без какой-либо спецификации, но мы никогда не должны полагаться на них и говорить, что они работают. это как теги obselete, они все еще работают, но мы должны прекратить их использовать, потому что однажды они перестанут работать. Так что да, это может быть полезно для людей, и мои комментарии также полезны, чтобы предупредить людей, что они должны знать, что это не официально.
Темани Афиф