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

У меня проблемы с пониманием поведения CSS :after имущество. Согласно спецификации ( здесь и здесь):

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

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

5 ответов

Решение

img а также input оба замененных элемента.

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

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

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

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

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

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

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

: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 и Chrome помещают сгенерированный контент в рамку с рамкой, которая является реализацией hr; содержание делает коробку выше. Firefox размещает содержимое обоих (!) Псевдоэлементов после горизонтального правила, которое является его реализацией hr, Этот вариант иллюстрирует виды проблем "взаимодействия", которые упоминаются в CSS 2.1.

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

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

Я потратил несколько часов на то, чтобы выщипывать волосы, только чтобы обнаружить, что какой-то другой переопределение css content (или же display:none) свойство моего селектора.

Например, если следующий код написан в другом месте, before или же after элемент никогда не будет отображаться:

         #id > child:before {
  content: none!important;
}
         <html>
<div id="id" class="class">
  <child>
    Before element is not showing
  </child>

</div>
<style>
  child:before {
    content: 'before';
    color: 'red';
  }
</style>

</html>

Просто найдите CSS, который перезаписывает ваш стиль, и спамите более сильные селекторы и !important заставить это работать

         #id>child:before {
  content: none!important;
}
         <html>
<div id="id" class="class">
  <child>
    Before element is <strong>showing</strong>
  </child>

</div>
<style>
  #id.class>child:before {
    content: 'before'!important;
    border: 1px solid red;
  }
</style>

</html>

<img> является заменяемым элементом, и использование псевдоэлементов :before или :after на нем работает, если изображение не загружается, а в противном случае оно не работает. Если вы собираетесь иметь запасной вариант на случай сбоя загрузки изображения, полезно использовать следующий css:

      img{ 
position: relative;
}

img:after{ 
position: absolute;
content: "Any allowed type of content including a fallback image";
left: 0;    
}

Хороший пример см. на странице https://css-tricks.com/7-practical-uses-for-the-before-and-after-pseudo-elements-in-css/ .

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

https://www.w3.org/TR/html5/syntax.html

Все Blink, 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%);
    }
  }
}
Другие вопросы по тегам