CSS content property: можно ли вставить HTML вместо текста?


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

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

это было бы вполне handy...It можно было бы сделать через Javascript, но использование css для этого действительно облегчит жизнь:)

3 189

3 ответа:

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

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

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

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

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

... это приведет к следующему результату:

BackTitle

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

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

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

  • вы не можете загрузить любую внешний ресурсы из этой разметки (ни УСБ, ни образов, ни СМИ и т. д.).
  • вы не можете выполнить скрипт.
  • поскольку это не будет частью DOM, единственный способ изменить его-передать разметку как dataURI и отредактировать этот dataURI в document.styleSheets. для этой части, DOMParser и XMLSerializer мая помогите.
  • в то время как эта же операция позволяет загрузите носитель с кодировкой url в <img> теги, это не будет работать в псевдо-элементах (по крайней мере, на сегодняшний день я не знаю, указано ли где-нибудь, что это не должно быть, поэтому это может быть еще не реализованная функция).

теперь небольшая демонстрация некоторой разметки 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>

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

пример CSS сгенерированный контент для Paged Media Module проект:

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

.runner { 
  position: running(heading);
}

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

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