and to change slides. 2 for comments. rvsp.github.io/CSS/generated

CSS: Generated Content

  • Generated Content
  • Generated Content: quotes
  • content: <image>
  • Generated Content: Attribute Values
  • position property
  • Generated Content: Counters
  • Generated Content: Strings
  • Special Characters
  • Accessibility
  • Design Elements
  • Exercise

rvsp.github.io/css/generated

Generated Content

::before and ::after

p::before {
  content: "before content - ";
  font-weight: bold;
}
p::after{
  content: " - after content";
  font-weight: bold;
}
<p>the content</p>

the content

<p>
    <before>before content - </before>
        the content
    <after> - after content</after>
</p>
Try it out

Try it out

Try it out

Pseudo Elements

You get 2 free stylable faux elements for every non-empty element

Content
Doesn't apply to replaced elements like <img> and <br>.

Syntax

element::before {
  /* the only 'required' attribute */
  content: ""; 
 }

element::after {
  /* without "content:", you have no content */
  content: ""; 
 }

Objects inserted using the content property are anonymous replaced elements.

content property

content: value;

none / normal
Same as no content property declared.
<image>
URL of a resource, usual an image
counter() / counters()
'counter(name), counter(name, style), 'counters(name, string)' or 'counters(name, string, style)'. 'name' is a string, but not 'none', 'inherit' or 'initial'.
string
A string of text. Can be combined with URL, counter, attr(x), quotes, etc.
open-quote / close-quote
The appropriate string set in the  'quotes' property.
no-open-quote / no-close-quote
Does not include quotes, but increments the level of nesting for quotes.
attr(X)
Displays the value of the attribute 'X'

content: value;

content: none;
content: normal;
content: "string of text";
content: url(path/image.jpg);

content: counter(mycounter, lower-roman);
content: counters(mycounter, '.', upper-roman);

content: open-quote;
content: close-quote;
content: no-open-quote;
content: no-close-quote;

content: attr(href)
content: url(path/email.png) " " attr(title);

content: inherit;
content: initial;
content: unset;

content: value;

  1. content: none
  2. content: normal
  3. content: open-quote; content: close-quote; content: no-open-quote; content: no-close-quote;
  4. content: <image>
  5. content: attr()
  6. content: counter() content: counters()
  7. content: <string>
  8. Examples

content: none

none

content: none;

Acts as display: none; on pseudo-elements

Basically, gets rid of the generated content if there was any added.

content: normal

normal

content: normal;

For ::before and ::after it's the same as none.

For ::marker it's as if no content was defined, as if set to initial.

For DOM elements, computes to contents, as if not set at all.

Generated Content: quotes

content and quote properties

Quotes are a two step process: definte the quote property, then use open-quote and close-quote as values for the content property.

/* Example: Pairs of quotes for two levels in three languages */
:lang(en) > q { quotes: '"' '"' "'" "'"; }
:lang(fr) > q { quotes: "«" "»" "’" "’"; }
:lang(de) > q { quotes: "«" "»" "‹" "›"; }

/* Insert quotes before and after <q> element's content */
q::before { content: open-quote }
q::after  { content: close-quote }
They'll alternate, even if they're on different elements

Play Time

Try it out

no-close-quote

Codepen.io

content: <image>

Try it out

Try it out

text is not parsed.

Try it out

Generated Content: Attribute Values

content: attr( attrname );

Attribute Values as content

This is a local link, and this is an external link.

Why relative only on hover?

This is a local link, and this is an external link.

Play

Open

attr() support

Supported

attr( attrName )

Examples:

@media print {
  a[href^="https://"]::after, 
  a[href^="http://"]::after  {
    content: " ("  attr(href) ")";
  }
}
abbr[title]:hover::after {
  content: attr(title);
  position: absolute; bottom: 0; right: 0;
  background-color: #ccc;
  border: 1px solid;
}

attr() support, or lack thereof

attr( attrName unit? [ , fallback ]? )

See MDN attr() function

<p data-count="5">Hi</p>

width: attr(data-count em, auto);

position property

position property

Sets how an element is positioned in a document. top, right, bottom, and left properties determine the final location of positioned (non static) elements.

static | relative | absolute | fixed | sticky
static
Default. Positioned according to the normal flow of the document. top, right, bottom, left, and z-index properties have no effect
relative
Positioned according to the normal flow of the document. Can be offset relative to itself by top, right, bottom, and left. Change in position does not move its siblings. z-index creates a new stacking context.
absolute
The element is removed from the normal document flow. No space is created for the element in the page layout. Positioned relative to its closest positioned ancestor, or the <body> if none, by the top, right, bottom, and left properties. Creates it's own block formatting context. Margins don't collapse. z-index creates a new stacking context.
fixed
Like absolute, element is removed from the normal document flow, positioned relative to the initial containing block established by the viewport, except when one of its ancestors has a transform, perspective, or filter property set. Position is determined by top, right, bottom, and left. When printed, it's placed in the same spot on every page.
sticky
Positioned according to the normal flow of the document, and then offset relative to its nearest scrolling ancestor and containing block (nearest block-level ancestor), based on the values of top, right, bottom, and left. Creates a new stacking context. It "sticks" to its nearest ancestor that has a "scrolling mechanism" (created when overflow is hidden, scroll, auto, or overlay), even if that ancestor isn't the nearest actually scrolling ancestor.

position property

static
Default. Positioned according to the normal flow of the document. top, right, bottom, left, and z-index properties have no effect
relative
Positioned according to the normal flow of the document. Can be offset relative to itself by top, right, bottom, and left. Change in position does not move its siblings. z-index creates a new stacking context.
absolute
The element is removed from the normal document flow. No space is created for the element in the page layout. Positioned relative to its closest positioned ancestor, or the <body> if none, by the top, right, bottom, and left properties. Creates it's own block formatting context. Margins don't collapse. z-index creates a new stacking context.

position property

We're interested in absolute, static & relative for right now

  • If not static, element is considered positioned
  • If positioned, it has it's own stacking context
  • If absolute, top, right, bottom, and left properties specify offsets from the edges of the element's containing block.
  • Containing block is the nearest "positioned" ancestor, or the <body>
  • If no height/width declared on absolute, top: 0; bottom: 0; left: 0; right: 0 will make it the size of it's parent
  • else, top overrides bottom and left overrides right.

top, bottom, left & right properties

<length> | <percentage> | auto

position: absolute;
Vertical and horizontal positions of element relative to positioned containing block ancestor

position: relative;
Vertical and horizontal positions of element compared to where it would have been otherwise positioned.

position: static;
Has no impact.

position property

position property

Generated Content: Counters

counter() & counters() styles

counter: counter(counter, style)
counter: counters(counter, string, style)
  • decimal
  • cjk-decimal
  • decimal-leading-zero
  • lower-roman
  • upper-roman
  • lower-greek
  • lower-alpha
  • lower-latin
  • upper-alpha
  • upper-latin
  • arabic-indic
  • armenian
  • bengali
  • cambodian
  • cjk-earthly-branch
  • cjk-heavenly-stem
  • cjk-ideographic
  • devanagari
  • ethiopic-numeric
  • georgian
  • gujarati
  • gurmukhi
  • hebrew
  • hiragana
  • hiragana-iroha
  • japanese-formal
  • japanese-informal
  • kannada
  • katakana
  • katakana-iroha
  • khmer
  • korean-hangul-formal
  • korean-hanja-formal
  • korean-hanja-informal
  • lao
  • lower-armenian
  • malayalam
  • mongolian
  • myanmar
  • oriya
  • persian
  • simp-chinese-formal
  • simp-chinese-informal
  • tamil
  • telugu
  • thai
  • tibetan
  • trad-chinese-formal
  • trad-chinese-informal
  • upper-armenian

Counter

Counter

Counter for this Deck

  • Elements that aren't displayed ('display: none') can't increment or reset a counter.
  • Pseudo-elements that aren't generated also don't increment or reset counters

content: counters()

Generated Content: Strings

Syntax

 element::before {
  content: "REQUIRED";
 }

 element::before {
    content: '';                  /* empty */
    content: " (.pdf) ";          /* any text */
    content: "\2603";             /* unicode */
    content: " (" attr(href) ")"; /* attributes */
    content: counter(name);
        counter-increment: name;  /* counters */
 }
    

Special Characters

Decorative Characters

<blockquote>
  <p>With generated content you can create text effects.</p>
  <p>We'll cover other uses next.</p>
</blockquote>

With generated content you can created text effects.

We'll cover other uses next.

Improved UX

a::before {
  font-size: 120%;
  padding: 2px 5px;
  display: inline-block;
  text-align: center;
}
a[href^="mailto:"]::before {
  content: "\2709 ";
}
a[href^="tel:"]::before {
  content: "\2706";
}
a[href$="vcs"]::before {
  content: "\231A";
}

Special Character

 element::before {
  content: "\2603";
 }

Try it out
Calculator

Quotes

This is a pull quote

.quote {
    border-radius: 10px; padding: 20px;
    position:relative;
    background-color: red; color: white;
}
.quote::after {
    position:absolute;
    content: '';
    width: 0; height:0;
    border: 20px solid transparent;
    border-top-color: red;
    bottom:-39px; left:20px;
}

Play

Open

Material Design Icons

Icon Fonts

Accessibility

Accessibility of Generated Content

Improved Accessibility (future)

content: url(question.svg) / "More Information";

Purely decorative

content: "\25BA" / "";

Design Elements

Thought bubbles

This is a thought bubble

.thought,.thought::before,
.thought::after  {
  border-radius: 50%;
  border: 5px solid blue;
  background-color: white;
  position:relative;
}
.thought::before,
.thought::after {
  content: '';
  position:absolute;
  left: 20%; bottom: -30px;
  height: 40px; width: 40px;
}
.thought::after {
  left: 12%; bottom: -50px;
  height: 20px; width: 20px;
}

Example

Example

Try it out:

Try it: Tool Tip

In this section you have learned the general idea of using generated content to create effects and / or to provide additional information. Try hovering over me to find out how awesome generated content can be.

Open up a text editor and try creating a tooltip without looking at the code. But, if you must, the code is attached, or you can check out your web inspector.

Here is one solution

Exercise

Let's add a few pseudo selectors we'll use and generate and position content on them. HTML is on the next page.

  1. Make each card 300px tall by 200px wide.
  2. Make the face and the back the same size, and in the same spot
  3. Add two pseudo element selector blocks for the face of each card
  4. Add generated content: the face value
  5. Make that content (the "A" in our current examples, but this should be automatically set), appear twice on the face of the card
  6. Place one of those valies 10 pixels from the upper left hand corner of the face of the card.
  7. Place the other A 10 pixels from the bottom righ hand corner of the face of the card.

Exercise

HTML for our code example

<figure>
  <div class="card" data-type="H">
    <div class="back"></div>
    <div class="face" data-value="A">♥</div>
  </div>
  <div class="card" data-type="C">
    <div class="back"></div>
    <div class="face" data-value="A">♣</div>
  </div>
  <div class="card" data-type="D">
    <div class="back"></div>
   <div class="face" data-value="A">♦</div>
  </div>
</figure>

 

This page intentionally left blank

Solution

Make each card 300px tall by 200px wide.

.card {
  height: 300px;
  width: 300px;
}

Make the face and the back the same size, and in the same spot

.card {
  height: 300px;
  width: 300px;
  position: relative;
}

Add two pseudo element selector blocks for the face of each card

  .face, 
  .back {
    position: absolute;
    top: 0; bottom: 0; left: 0; right: 0;
}

Add generated content: the face value

Make that content (the "A" in our current examples, but this should be automatically set), appear twice on the face of the card

Place one of those valies 10 pixels from the upper left hand corner of the face of the card.

Place the other A 10 pixels from the bottom righ hand corner of the face of the card.

[data-value]:after,
[data-value]:before {
  content: attr(data-value);
  position: absolute;
}
.face::before {
  top: 10px;
  left: 10px;
}
.face::after {
  bottom: 10px;
  right: 10px;
}

Media Queries

Next ➹