Подтвердить что ты не робот

Что такое псевдоним элемента:: content/:: slotted и как он работает?

Это невозможно для Google, потому что каждая статья, описывающая псевдоэлементы :before и :after, похоже, использует слово "контент".

Я слышал об этом в статье этой статьи CSS-Tricks, объясняя, как реализовать слайдер изображения в качестве примера использования для веб-компонентов. Пример кода, который он отображается внутри, таким образом:

CSS

#slides ::content img {
   width: 25%;
   float: left;
}

HTML

<template>
  ...
  <div class="inner">
    <content select="img"></content>
  </div>
</template>

Кажется, что это относится к этому тегу <content>, который используется, чтобы позволить пользователю включать веб-компоненты, но я хотел бы это глубже понять.

EDIT:

После прочтения далее в вышеупомянутой статье я обнаружил ссылку автора "Shadow DOM CSS Cheatsheet", которая содержит отрывок, который объясняет, что псевдоэлемент ::content:

Выбор распределенных узлов внутри элемента. Нужно спариваться с polyfill -next-селектором для браузеров, которые не поддерживают собственный селектор.

::content h1 {
    color: red;
}

Источник: http://robdodson.me/blog/2014/04/10/shadow-dom-css-cheat-sheet/

Это полезно, но я все еще считаю, что все дело довольно непрозрачное. Любые дополнительные сведения?

4b9b3361

Ответ 1

Псевдоэлемент ::content заменяется в будущих реализациях Web Components/Shadow DOM с помощью ::slotted. Аналогично, элемент, на который ссылается этот псевдоэлемент, изменился с <content на <slot > в последней версии Спецификация Shadow DOM. Вы можете увидеть соответствующую дискуссию об этом изменении здесь.

В настоящее время браузеры поддерживают <content> и ::content.


Оригинальный ответ:


Резюме:

::content - это, по сути, способ выкапывать более глубокие и стильные потомки ShadowHost, которые обычно не доступны для стилей, потому что ваш CSS не знает, как искать фрагмент ShadowDOM без ::content.


Этот ответ предполагает, что вы, по крайней мере, знакомы с элементом <template> и Веб-компоненты, в частности ShadowDOM, который имеет дело с ShadowTree и их двумя основными элементами ShadowHost и ShadowRoot.

Примечание. На момент написания этой статьи поддерживается поддержка менее 50% (даже префикс, поддержка по умолчанию) для веб-компонентов в пяти основных браузерах. Хотя все современные браузеры поддерживают <template>, только последние версии Chrome и Opera полностью поддерживают ShadowDOM; с поддержкой Firefox его частей после переключения требуемой функции в about:config (dom.webcomponents.enabled) на истина.

Цель использования ShadowDOM похожа на MVC разделение проблем. То есть мы хотим отделить наш контент от нашей презентации и разрешить инкапсулированные шаблоны в нашем коде, чтобы сделать его более управляемым. У нас это уже есть на разных языках программирования, но в течение некоторого времени он оставался проблемой в HTML и CSS. Кроме того, при стилизации элементов в веб-приложениях могут возникать конфликты с именами классов.

Обычно мы взаимодействуем с LightDOM (своего рода "Светлое царство" ), но иногда полезно использовать инкапсуляцию. Пересечение этого типа "Shadow Realm" (часть веб-компонентов) - это новый метод предотвращения упомянутых выше проблем с помощью , позволяющего инкапсуляцию. Любые стили, применяемые к разметке в ShadowTree, не будут применяться к разметке вне вашего ShadowTree, даже если используются одни и те же классы или селектора.

Когда ShadowTree (который живет в ShadowDOM) имеет дерево из LightDOM, распределенное внутри него, и/или когда рендерит ShadowTree, результат преобразуется браузером в то, что называется составленное дерево.

Когда браузер отображает ваш код, контент распространяется и вставляется в новых местах, кроме тех, где он был физически типизирован. Этот распределенный вывод - это то, что вы видите (и то, что видит браузер), и называется composed tree. На самом деле, контент изначально не набирается в том порядке, в котором он сейчас появляется, но вы этого не узнаете, и браузер не будет. Это разделение между "конечным результатом" и "исходным кодом", если хотите, является одним из основных преимуществ инкапсуляции.

Веб-компоненты и будущее CSS - отличное 40-минутное видео на веб-компонентах и, в частности, ShadowDOM, указал мне на ZachSaucier.


В зависимости от вашего вопроса псевдо-элемент ::content применяется к тем, которые называются распределенными узлами. Распределенный node - это еще один термин для всех тегов <content></content>. Содержимое распространяется со своего места в исходной разметке туда, где вы разместили теги <content> в шаблоне.

Итак, когда вам нужна специфика CSS, одним из способов управления дескрипторами обычно является то, что вы переходите к родительскому элементу и добавляете его как часть селектора. Пример: если .container {} недостаточно специфичен, вы можете использовать div .container {} или .main .container {}, чтобы заставить ваш селектор работать.

Размышляя о точке ShadowDOM, которая просматривает и инкапсулирует, вы должны понимать, что этот новый ShadowTree, который вы создали, является полностью новым (дискретным) фрагментом DOM. Это не в том же "Светлом царстве", что и остальная часть вашего контента; это в "Области теней". Итак, как CSS знает, чтобы нацелиться на это "Теневое царство"? Используя псевдоэлемент ::content!

Сегмент псевдоэлементов ::content действует как родительский элемент распределенных узлов.

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

Например, см. эту измененную и улучшенную версию (Leo) кода из HTML5Rocks:

var div = document.querySelector('div');
var root = div.createShadowRoot();
var template = document.querySelector('template');

root.appendChild(template.content);
<template>
  <style>
    h3 { color: red; }
    content[select="h3"]::content > h3 { color: green; }
    ::content section p { text-decoration: underline; }
  </style>
  <h3>Shadow DOM</h3>
  <content select="h3"></content>
  <content select="section"></content>
</template>

<div>
  <h3>Light DOM</h3>
  <section>
    <div>I'm not underlined</div>
    <p>I'm underlined in Shadow DOM!</p>
  </section>
</div>