This content originally appeared on Web development blog - Manuel Matuzović and was authored by Manuel Matuzović
This is part 3 of my series Here’s what I didn’t know about… in which I try to learn new things about CSS. This time I'm trying to find out what I didn’t know about the content
property.
A few weeks ago Stefan published a post on his website called “The CSS "content" property accepts alternative text”, which blew my mind. He showed that the content
property excepts 2 values and not just 1, the actual content and an alternative text.
.new-item::before {
/* "Highlighted item" and element content is read out */
content: '★' / 'Highlighted item';
}
I didn’t know that and I was wondering if there were more things I didn’t know about the content
property. Since you’re reading this, I found something, so let’s see what I was able to add to my “Here’s what I didn’t know about…” series.
How I’m using the content attribute.
Before I started my research, I was using this property primarily for 3 things.
Adding an element to another element using pseudo elements
If I want to create a simple shape in CSS that is not a rectangle or circle, I use :after
and ::before
to give myself more options for styling.
<div></div>
div {
width: 70px;
height: 50px;
margin-top: 15px;
border: 5px solid #123456;
border-radius: 5px;
position: relative;
}
div::before {
content: '';
position: absolute;
left: 0;
right: 0;
top: -16px;
width: 20px;
height: 20px;
margin: auto;
border: solid #123456;
border-width: 5px 5px 0 0;
border-radius: 5px;
transform: rotate(-45deg);
background: #fff;
}
Checkout example 1 on CodePen.
To render on screen, the pseudo elements needs the content
attribute.
Revealing URLs in print styles sheets
Printed links are useless if you don’t know where there are leading. I’m using a combination of content
and the attr()
function in print style sheets to display URLs next to their linked text.
@media print {
a[href^="http://"]:after,
a[href^="https://"]:after
{
content: ' (' attr(href) ')';
}
}
Custom counters
Every now and then I need custom counters in lists. A combination of content
and counter properties usually does the job.
- Element 001
- Element 002
- Element 003
<ol>
<li>Element 001</li>
<li>Element 002</li>
<li>Element 003</li>
</ol>
ol {
list-style-type: none;
counter-reset: mylist;
}
li {
counter-increment: mylist;
}
li::before {
content: '? ' counter(mylist) ': ';
}
Checkout example 2 on CodePen.
Have a look at Here’s what I didn’t know about list-style-type for more options to style list items.
Now, let’s see what else content
can do for us. Here’s what I’ve learned recently:
Content accepts images and gradients
I knew that content
accepts the counter
and attr
functions, but it never came to my mind that it might allow other functions, as well. Whenever I needed an image in a pseudo element, I would use background-image
, although content
would've worked, too.
div::before {
content: url('pin.png');
}
Checkout example 3 on CodePen.
If this works with images, it should work with gradients too, right? Yeah, well, no. Chrome seems to be the only browser that renders pseudo elements with gradient content values.
div::before {
content: linear-gradient(blue, red);
height: 50px;
width: 50px;
display: block;
border: 1px solid red;
}
Checkout example 4 on CodePen.
You can define alt text for content values (…in Chrome)
What’s the point of using content
when background-image
has better support? The reason Stefan wrote his post, content
supports alt text.
div::before {
content: url('pin.png') / 'You are here.';
}
Checkout example 5 on CodePen.
Unfortunately, this only works in Chrome (tested on macOS 10.15.4, Chrome 81 with VoiceOver). Firefox and Safari don't even render the pseudo element because the value is invalid. Too bad.
Even if this worked in most browsers, I wouldn’t recommend adding text content to a CSS file. Others working on the project probably wouldn’t expect text coming from a CSS file, things might get messy on sites with multiple languages, auto-translation may not work, and the content is only accessible if the CSS loads successfully. Adrian Roselli shares an example of a poor practice in Link Targets and 3.2.5.
You can combine text and images
Nor did I know that you can use the url()
function as a value, I also didn’t know that you can combine it with text.
div::before {
content: url('pin.png') 'You are here.';
}
Checkout example 6 on CodePen.
You can only replace the content of a regular element with an <image>
The content
property is meant to be used with pseudo elements. You can’t use it to replace a string in an element with another string. This won’t work:
div {
content: 'You are here';
}
But you can use it to replace a string with an image. The string is still in the DOM but screen readers announce the filename. (You can do it, but you shouldn’t.)
<div>You are here!</div>
div {
content: url('pin.png');
}
Checkout example 7 on CodePen.
There are quotes and no-quotes
Okay, now this one is really cool. Let’s say we have a quote nested in another quote.
<blockquote>
My mama always said,
<q>
Life was like a box of chocolates. You never know what you’re gonna get </q
>.
</blockquote>
My mama always said,Life was like a box of chocolates. You never know what you’re gonna get.
What you should see in the above example is that the blockquote
has no quotes and q
has double quotes.
If we add opening and closing quotes to the blockquote
using pseudo elements and the content
property, the blockquote
now displays double quotes and the q
automatically single quotes.
blockquote::before {
content: open-quote;
}
blockquote::after {
content: close-quote;
}
My mama always said,Life was like a box of chocolates. You never know what you’re gonna get.
Nice! To top it all off, we can even have a combination of the two variations, blockquote
with no quotes and q
with single quotes.
blockquote::before {
content: no-open-quote;
}
blockquote::after {
content: no-close-quote;
}
My mama always said,Life was like a box of chocolates. You never know what you’re gonna get.
The no-open-quote
and no-close-quote
keywords don’t insert anything, but increment the quotation depth by one.
Nested quotes in different languages
Just because I was curious, here are some variations of the second example in other languages.
French
<blockquote lang="fr">
Maman disait toujours,
<q>
la vie, c'est comme une boîte de chocolats: on ne sait jamais sur quoi on va
tomber </q
>.
</blockquote>
Maman disait toujours,
la vie, c'est comme une boîte de chocolats: on ne sait jamais sur quoi on va tomber
.
Russian
<blockquote lang="ru">
Моя мама всегда говорила,
<q>
Жизнь как коробка шоколадных конфет: никогда не знаешь, какая начинка тебе
попадётся </q
>.
</blockquote>
Моя мама всегда говорила,
Жизнь как коробка шоколадных конфет: никогда не знаешь, какая начинка тебе попадётся
.
German
<blockquote lang="de">
Mama hat immer gesagt,
<q>
Das Leben ist wie eine Schachtel Pralinen. Man weiß nie, was man kriegt </q
>.
</blockquote>
Mama hat immer gesagt,
Das Leben ist wie eine Schachtel Pralinen. Man weiß nie, was man kriegt
.
Spanish
<blockquote lang="es">
Mi mamá siempre decía,
<q>
La vida es como una caja de bombones, nunca sabes lo que vas a conseguir </q
>.
</blockquote>
Mi mamá siempre decía,
La vida es como una caja de bombones, nunca sabes lo que vas a conseguir
.
Sorry, if I fucked up any of the translations.
There’s counter() and counters()
I'm really not sure if I was aware of the fact there isn’t just a counter()
but also a counters()
function. However, the difference is that counters()
enables nested custom counters.
-
Element 001
- Element 001
- Element 002
- Element 003
- Element 002
- Element 003
<ol>
<li>
Element 001
<ol>
<li>Element 001</li>
<li>Element 002</li>
<li>Element 003</li>
</ol>
</li>
<li>Element 002</li>
<li>Element 003</li>
</ol>
ol {
list-style-type: none;
counter-reset: mylist;
}
li {
counter-increment: mylist;
}
li::before {
content: '? ' counters(mylist, '.') ': ';
}
Checkout example 8 on CodePen.
You’ll find more ways of using the content
property in Adrian’s article https://adrianroselli.com/2019/12/showing-file-types-in-links.html.
Wow, that was a lot. I didn’t expect to write and learn so much. I hope that you’ve learned as much as I did.
Thanks for reading ❤️ and thanks to Stefan for the inspiration for this post.
Updates
28.05.2020 Added a disclaimer about putting text in CSS files, and a link to an article by Adrian Roselli.
This content originally appeared on Web development blog - Manuel Matuzović and was authored by Manuel Matuzović
Manuel Matuzović | Sciencx (2020-05-26T06:58:54+00:00) Here’s what I didn’t know about “content”. Retrieved from https://www.scien.cx/2020/05/26/heres-what-i-didnt-know-about-content/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.