CSS content property: is it possible to insert HTML instead of Text?

HtmlCssPseudo ElementCss Content

Html Problem Overview


Just wondering if it's possible somehow to make the CSS content property insert html code instead string on :before or :after an element like:

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

this would be quite handy...It could be done through Javascript but using css for this would really make lives easier :)

Html Solutions


Solution 1 - Html

Unfortunately, this is not possible. Per the spec:

> Generated content does not alter the document tree. In particular, it is not fed back to the document language processor (e.g., for reparsing).

In other words, for string values this means the value is always treated literally. It is never interpreted as markup, regardless of the document language in use.

As an example, using the given CSS with the following HTML:

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

... will result in the following output:

<a href="#top">Back</a>Title

Solution 2 - Html

As almost noted in comments to @BoltClock's answer, in modern browsers, you can actually add some html markup to pseudo-elements using the (url()) in combination with svg's <foreignObject> element.

You can either specify an URL pointing to an actual svg file, or create it with a dataURI version (data:image/svg+xml; charset=utf8, + encodeURIComponent(yourSvgMarkup))

But note that it is mostly a hack and that there are a lot of limitations :

  • You can not load any external resources from this markup (no CSS, no images, no media etc.).
  • You can not execute script.
  • Since this won't be part of the DOM, the only way to alter it, is to pass the markup as a dataURI, and edit this dataURI in document.styleSheets. for this part, DOMParser and XMLSerializer may help.
  • While the same operation allows us to load url-encoded media in <img> tags, this won't work in pseudo-elements (at least as of today, I don't know if it is specified anywhere that it shouldn't, so it may be a not-yet implemented feature).

Now, a small demo of some html markup in a pseudo element :

/* 
**  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>

Solution 3 - Html

In CSS3 paged media this is possible using position: running() and content: element().

Example from the CSS Generated Content for Paged Media Module draft:

@top-center {
  content: element(heading); 
}
   
.runner { 
  position: running(heading);
}

.runner can be any element and heading is an arbitrary name for the slot.

EDIT: to clarify, there is basically no browser support so this was mostly meant to be for future reference/in addition to the 'practical answers' given already.

Solution 4 - Html

It is not possible prolly cuz it would be so easy to XSS. Also , current HTML sanitizers that are available don't disallow content property.

(Definitely not the greatest answer here but I just wanted to share an insight other than the "according to spec... ")

Solution 5 - Html

If you have the ability to add a HTML elsewhere on the page, you can reposition it over the area where your CSS content shows up.

So you add your CSS content:

   .cssClass::after {
    content: "Content and Words and Things";
    color: #0000EE;
        }

I added hyperlink blue so it looks like a link.

Then you add an href that has no text in between the tags with an id or class that you can reference. It can be anywhere as long as it's on the same page.

<a id="link" href="#"></a>

And then position the link over the content where you want it:

a#link{
    height: 20px;
    width: 100%;
    left: 0;
    top: 5%;
    position: absolute;
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionzanonaView Question on Stackoverflow
Solution 1 - HtmlBoltClockView Answer on Stackoverflow
Solution 2 - HtmlKaiidoView Answer on Stackoverflow
Solution 3 - Htmls-olView Answer on Stackoverflow
Solution 4 - HtmlTilak MaddyView Answer on Stackoverflow
Solution 5 - HtmlLibrarianLaurenView Answer on Stackoverflow