What are good uses of the css `content` property?
Does css "content" property break the rule of content and separation because css is for presentation not to generation content?
Good point. I'd say it does if it's used for actual data.
The quirksmode page on content shows the limitations pretty well. You can't add any kind of styled content at the moment - it will work with too few browsers. You can add only character data.
The author of the quirksmode airs an interesting opinion:
I feel that we shouldn't use the content declaration at all. It adds content to the page, and CSS is meant for adding presentation to the page, and not content. Therefore I feel that you should use JavaScript if you want to dynamically generate content. CSS is the wrong tool for this job.
I agree with this in general, but sometimes there may be cases where you don't want to rely on JavaScript to do the job. The comma example shown by Martin is a case where I find using content
justified (although I personally would be feeling better if the commas would already be served coming from server side - it's what I personally would stick to.)
Also, keep in mind that adding commas and quotes through the content
property may look bad when your content is viewed from elsewhere - for example in a search results page.
I'd say use it only sparingly, if you really need it.
Various possible uses of the content: property in css2/css3
Oh, too many to list. Some of the most common cases are:
Special numbering, with the
counter()
function, along with thecounter-reset
andcounter-increment
propertiesPure CSS clearfix with:
.foo:after {
content: "";
display: block;
clear: both;
}Display attributes, eg to print URLs for hyperlinks in a print stylesheet
a[href]:after {
content: ' (' attr(href) ') ';
}Add typographic ornaments that shouldn't be in the HTML because they're presentational. For example, in my blog, I've used it for the ornaments between posts or sidebar links.
Add icons to hyperlinks, depending on where they point, like
a[href^="http://twitter.com/"]:before {
content: url('twitter-icon.png');
}Adding a pointer to make a CSS-only speech bubble:
.bubble {
position: relative;
background: silver;
}
.bubble:after {
content: "";
border:10px solid transparent;
border-top-color:silver;
position: absolute;
bottom:-20px
}
And many, many other.
Just beware: If something is not presentational, it should probably be in your HTML. Users will not be able to select CSS generated content, and screen readers will ignore it.
content property in CSS
Using content
property embeds a virtual content inside an element, it is used with a pseudo :before
or :after
, so if you use :before
, the content will be embedded before.
From MDN :
The
content
CSS property is used with the::before
and::after
pseudo-elements to generate content in an element. Objects inserted
using thecontent
property are anonymous replaced elements.
Content property can hold any character, number, entities. For more information, you can refer an article here.
Also, you can get an handy converter here.
This method is also used by font-awesome - Example and other related svg font embedding libraries, where you can simply call classes to the elements and the fonts will be embedded virtually.
Also, just a side information, content generated using CSS content
property is inline
by default, also this is rendered inside the element and not outside..
Why do the :before and :after pseudo-elements require a 'content' property?
The reason you need a content: ''
declaration for each ::before
and/or ::after
pseudo-element is because the initial value of content
is normal
, which computes to none
on the ::before
and ::after
pseudo-elements. See the spec.
The reason the initial value of content
isn't an empty string but a value that computes to none
for the ::before
and ::after
pseudo-elements, is twofold:
Having empty inline content at the start and end of every element is rather silly. Remember that the original purpose of the
::before
and::after
pseudo-elements is to insert generated content before and after the main content of an originating element. When there's no content to insert, creating an additional box just to insert nothing is pointless. So thenone
value is there to tell the browser not to bother with creating an additional box.The practice of using empty
::before
and::after
pseudo-elements to create additional boxes for the sole purpose of layout aesthetics is relatively new, and some purists might even go so far as to call it a hack for this reason.Having empty inline content at the start and end of every element means that every (non-replaced) element — including
html
andbody
— would by default generate not one box, but up to three boxes (and more in the case of elements that already generate more than just the principal box, like elements with list styles). How many of the two extra boxes per element will you actually use? That's potentially tripling the cost of layout for very little gain.Realistically, even in this decade, less than 10% of the elements on a page will ever need
::before
and::after
pseudo-elements for layout.
And so these pseudo-elements are made opt-in — because making them opt-out is not only a waste of system resources, but just plain illogical given their original purpose. The performance reason is also why I do not recommend generating pseudo-elements for every element using ::before, ::after
.
But then you might ask: why not have the display
property default to none
on ::before, ::after
? Simple: because the initial value of display
is not none
; it is inline
. Having inline
compute to none
on ::before, ::after
is not an option because then you could never display them inline. Having the initial value of display
be none
on ::before, ::after
is not an option because a property can only have one initial value. (This is why the initial value of content
is always normal
and it is simply defined to compute to none
on ::before, ::after
.)
Why do I need an empty `content` property on an ::after pseudo-element?
You cannot style generated content without defining what that content should be. If you don’t really need any content, just an extra “invisible element” to style, you can set it to the empty string (content: ''
) and just style that.
It’s easy to confirm this yourself: http://jsfiddle.net/mathias/YRm5V/
By the way, the snippet you posted is the micro clearfix hack, which is explained here: http://nicolasgallagher.com/micro-clearfix-hack/
As for your second question, you’ll need an HTML5 shiv (small piece of JavaScript) to make <nav>
stylable in some older browsers.
CSS content property: is it possible to insert HTML instead of Text?
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
Related Topics
Workaround for CSS Variables in Ie
Inject CSS with Chrome Developer Tool
Position One Element Relative to Another in CSS
CSS Flexbox Vertically/Horizontally Center Image Without Explicitely Defining Parent Height
How to Create Zebra Stripes on HTML Table Without Using JavaScript and Even/Odd Classes Generation
How to Colorize a White Png Image with CSS Only
CSS 62.5% Why Do Developers Use It
Multiple Classes in CSS Selector
CSS Negative Z-Index: What Does It Mean
Inline CSS Formatting Best Practices - Two Questions
How to Adjust the Caret (Blinking Cursor) Size Inside Searchbar with CSS
Using a Percentage Margin in CSS But Want a Minimum Margin in Pixels