Свойство CSS-содержимого: возможно ли вставить HTML вместо текста?

Просто интересно, возможно ли каким-либо образом сделать свойство CSS content вставить html-код вместо строки на :before или :after, например:

.header:before{
  content: '<a href="#top">Back</a>';
}

Это было бы очень удобно... Это можно сделать с помощью Javascript, но с помощью css для этого было бы проще сделать жизнь проще:)

Ответ 1

К сожалению, это невозможно. По spec:

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

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

В качестве примера, используя данный CSS со следующим HTML:

<h1 class="header">Title</h1>

... приведет к следующему выводу:

< a href= "# top" > Назад </a> Название

Ответ 2

Как уже отмечалось в комментариях к @BoltClock, в современных браузерах, вы можете добавить некоторую html-разметку в псевдоэлементы, используя (url()) в сочетание с элементом svg <foreignObject>.

Вы можете указать URL-адрес, указывающий на фактический файл svg, или создать его с версией dataURI (data:image/svg+xml; charset=utf8, + encodeURIComponent(yourSvgMarkup))

Но обратите внимание, что это в основном хак и что много ограничений:

  • Вы не можете загружать ресурсы из внешнего из этой разметки (без CSS, без изображений, без носителя и т.д.).
  • Вы не можете выполнить script.
  • Поскольку это не будет частью DOM, единственный способ изменить его - передать разметку в качестве dataURI и отредактировать этот dataURI в document.styleSheets. для этой части DOMParser и XMLSerializer может помочь.
  • В то время как одна и та же операция позволяет нам загружать кодированные по URL-адресам носители в тегах <img>, это не будет работать в псевдоэлементах (по крайней мере, на сегодняшний день я не знаю, указано ли это где угодно, 't, так что это может быть еще не реализованная функция).

Теперь небольшая демонстрация некоторой html-разметки в псевдоэлементе:

/* 
**  original svg code :
*
*<svg width="200" height="60"
*     xmlns="http://www.w3.org/2000/svg">
*
* <foreignObject width="100%" height="100%" x="0" y="0">
*	<div xmlns="http://www.w3.org/1999/xhtml" style="color: blue">
*		I am <pre>HTML</pre>
*	</div>
* </foreignObject>
*</svg>
*
*/
#log::after {
  content: url('data:image/svg+xml;%20charset=utf8,%20%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20height%3D%2260%22%20width%3D%22200%22%3E%0A%0A%20%20%3CforeignObject%20y%3D%220%22%20x%3D%220%22%20height%3D%22100%25%22%20width%3D%22100%25%22%3E%0A%09%3Cdiv%20style%3D%22color%3A%20blue%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxhtml%22%3E%0A%09%09I%20am%20%3Cpre%3EHTML%3C%2Fpre%3E%0A%09%3C%2Fdiv%3E%0A%20%20%3C%2FforeignObject%3E%0A%3C%2Fsvg%3E');
}
<p id="log">hi</p>

Ответ 3

В CSS3 paged media это возможно с помощью position: running() и content: element().

Пример из Созданный CSS-контент для Paged Media Module черновик:

@top-center {
  content: element(heading); 
}

.runner { 
  position: running(heading);
}

.runner может быть любым элементом, а heading - произвольное имя для слота.

РЕДАКТИРОВАТЬ:, чтобы уточнить, в основном нет поддержки браузеров, поэтому в основном это предназначалось для будущей ссылки/в дополнение к уже полученным "практическим ответам".