ISTA 230

ISTA 230 - Introduction to Web Design

CSS–Generated Elements

CSS

CSS

Review

CSS

CSS

Pseudo-Elements

CSS

CSS

Pseudo-Elements

As previously discussed, HTML should be used for providing structure, organization, and meaning. Conversely, CSS should be used for modifying the display/presentation of the page (i.e., make it look nice).

CSS pseudo-elements allow us to inject content into our HTML using the :before and :after pseudo selectors. Using pseudo-elements, we can add an inline element before/after an element's content. The generated content is a child of the element, but is not actually part of the HTML!!! Because of this, many screen readers and other accessibility devices will ignore the content generated. Because of this, you should only use CSS-generated content for display-related content only (i.e., content that enhances your page but is not vital to understanding the content).

div:before
{
...
}

CSS

CSS

Pseudo-Elements

CSS

CSS

Pseudo-Elements

To create CSS-generated content, you'll need to create a CSS selector that includes the desired pseudo-element. Additionally, you must specify a 'content' property.

div:before
{
   content: contentGoesHere;
}

The 'content' property can contain a string of text, a link to an external file, element attributes, or counters. We'll explore each of these on the following slide.

It is important to note that CSS-generated content does not work with what the CSS specification refers to as 'replaced elements'. This includes the following elements:

CSS

CSS

Pseudo-Elements

CSS

CSS

Generated Elements - Text

Using CSS pseudo-elements, we can insert additional text into our web pages. Consider the following <div> element:

<div>
   This is my content.
</div>
      
This is my content.

Using our CSS pseudo-element selectors, we can add content before or after the text, "This is my content."

div:before
{
   content: "Content: ";


}
      
This is my content.

As you can see, the text "Content: " was added before the text specified in the HTML ("This is my content.") Alternatively, we could have added our dynamically generated content after the text in the HTML by using ":after" instead of ":before".

CSS

CSS

Generated Elements - Text

div:before
{
   content: "Content: ";


}
      
This is my content.

CSS

CSS

Generated Elements - Text

div:after
{
   content: "... some of which is CSS-generated!";


}
      
This is my content.

CSS

CSS

Generated Elements - Text

In addition to specifying the content for our pseudo-elements, we can also apply all other CSS properties that would apply to an inline element (such a span).

div:after
{
   content: "... some of which is CSS-generated!";
   font-weight:bold;
   background-color:yellow;
}
      
This is my content.

CSS

CSS

Generated Elements - Text

div:after
{
   content: "... some of which is CSS-generated!
             This is awesome";
}
      
This is my content.

CSS

CSS

Generated Elements - Text

div:after
{
   content: "... some of which is CSS-generated!<br />This is awesome";
}
      
This is my content.

CSS

CSS

Generated Elements - Text

div:after
{
   content: "... some of which is CSS-generated!\nThis is awesome";
}
      
This is my content.

CSS

CSS

Generated Elements - Text

CSS

CSS

Generated Elements - Text

div:after
{
   content: "... some of which is CSS-generated!\10This is awesome";

}
      
This is my content.

CSS

CSS

Generated Elements - Text

CSS

CSS

Generated Elements - Text

div:after
{
   content: "... some of which is CSS-generated!\aThis is awesome";

}
      
This is my content.

CSS

CSS

Generated Elements - Text

If we wanted to add a new line to our dynamically generated content, we would find that some simple tasks aren't so simple when it comes to using pseudo-elements. Initally, we might try simply pressing enter at the point we want our line break. However, this would result in our CSS becoming invalid! We might also try adding an HTML break (<br>). However, this wouldn't quite do what we intended...

div:after
{
   content: "... some of which is CSS-generated!<br />This is awesome";
}
      
This is my content.

Next, we might try adding a newline using '\n', a common approach in many programming languages. However, we'd soon find that this, too, doesn't do what we'd like.

div:after
{
   content: "... some of which is CSS-generated!\nThis is awesome";
}
      
This is my content.

Instead of using any of the approaches listed above, we should instead use the ASCII code for a newline. The ASCII code for a newline character is '10' in decimal or 'a' in hexidecimal. For CSS-generated content, we need to use the hexidecimal value.

While this will, in fact, insert a newline character in our dynamically generated content, the newline will have no effect on the presentation of our content. This is because, by default, HTML ignores extra white space (i.e., multiple spaces and/or new line characters). In order to display the new line character, we can use another CSS property called 'white-space'. This property allows us to specify how white-space should be displayed within a given element. By default, white-space is ignored ('normal'). However, we can force the element to display white-space in the same way as a <pre> element by setting it to 'pre'.

div:after
{
   content: "... some of which is CSS-generated!\aThis is awesome";
   white-space: pre;
}
      
This is my content.

CSS

CSS

white-space Property

pre { white-space: normal; }
div { white-space: pre; }
/*
 * Specifies how white-space should be displayed
 * within a given element. Options are:
 * normal, nowrap, pre, pre-line, and pre-wrap.
 * 
 * 
 * Default Value: normal
 * Inherited: Yes
 *
 */

CSS

CSS

Generated Elements - Text

                 | New Lines | Spaces & Tabs | Text Wrap |
       ----------+-----------+---------------+-----------+
       normal    |  Ignored  |    Ignored    |    Wrap   |
       nowrap    |  Ignored  |    Ignored    |  No Wrap  |
       pre       | Preserved |   Preserved   |  No Wrap  |
       pre-wrap  | Preserved |   Preserved   |    Wrap   |
       pre-line  | Preserved |    Ignored    |    Wrap   |
      

CSS

CSS

Generated Elements - Text

<p>
   I &hearts; NY<br />

</p>
      
I ♥ NY

CSS

CSS

Generated Elements - Text

<p>
   I &hearts; NY<br />
   I &#9829; NY
</p>
      
I ♥ NY
I ♥ NY

More HTML entities...

CSS

CSS

Generated Elements - Text

div:after
{
   content: "I &hearts; NY";
}
      
This is my content.

CSS

CSS

Generated Elements - Text

div:after
{
   content: "I &#9829; NY";
}
      
This is my content.

CSS

CSS

Generated Elements - Text

div:after
{
   content: "I \9829 NY";
}
      
This is my content.

CSS

CSS

Generated Elements - Text

982910 = ____16

CSS

CSS

Generated Elements - Text

982910 = 266516

CSS

CSS

Generated Elements - Text

In much the same way, we can insert HTML elements into our dynamically generated content. Up until this point, we've relied on the HTML entity name when adding them to our content. For example, we would use '&hearts;' to display a small heart character. However, we could use the HTML entity number instead of the name if we so desired. For the heart character, the HTML number would be '9829'.

<p>
   I &hearts; NY<br />
   I &#9829; NY
</p>
      
I ♥ NY
I ♥ NY

To add an HTML element to our CSS-generated content, we'll need to use the hexidecimal version of the HTML entity number. For our heart character, we know that 982910 is equal to 266516. Thus, we would use the following to add our HTML heart entity to our CSS-generated content.

div:after
{
   content: "I \2665 NY";
}
      
This is my content.

It's worth noting that in the above example, the space after our heart character is missing in the final display. To get around this, we can take one of two approaches:

div:after
{
   content: "I \2665" " NY"; /*** Break our content into two strings ***/
}
div:after
{
   content: "I \2665 \0020 NY"; /*** OR use the hexidecimal ASCII code for a blank space ***/
}

CSS

CSS

Generated Elements - Text

div:after
{
   content: "I \2665" " NY";
}
      
This is my content.

CSS

CSS

Generated Elements - Text

div:after
{
   content: "I \2665 \0020 NY";
}
      
This is my content.

CSS

CSS

Generated Elements - External Files

<a class="external" href="http://google.com">http://google.com</a>
      
      

CSS

CSS

Generated Elements - External Files

We can also use CSS-generated content to add external files to our page. For example, some sites add a small icon to any links on their page that will take the user to another site. We can do this using pseudo-elements by specifying a URL for our content property.

<a class="external" href="http://google.com">http://google.com</a>
a.external:after
{
   content: url("../images/external.png");
}
      
      

Note: While the above example is valid, it is not the most common approach to implementing an 'external link' icon. Instead, most designers use a combination of padding and a background image to achieve the same effect. While the difference is not noticed by most users, the padding/background-image approach is a better choice since it is better supported and provides additional benefits when we move to CSS 3.

CSS

CSS

Generated Elements - Attributes

<a href="http://google.com">Google</a>
      
      

CSS

CSS

Generated Elements - Attributes

In addition to adding text to our content via CSS, we can also use pseudo-elements to display the value of element attributes. For example, we could dynamically add the value of a hyperlink's href attribute after it.

<a href="http://google.com">Google</a>
a:after
{
   content: attr(href); /* Notice, no quotes! */
}
      
      

We could combine this approach with our previous examples to provide a more readable example:

a:after
{
   /* We can combine content pieces */
   content: " [" attr(href) "] ";
   font-style:italic;
   color:#aaa;
}
      
      

CSS

CSS

Generated Elements - Attributes

<a href="http://google.com">Google</a>
a:after
{
   /* We can combine content pieces */
   content: " --" attr(href) "-- ";


}
      
      

CSS

CSS

Generated Elements - Attributes

<a href="http://google.com">Google</a>
a:after
{
   /* We can combine content pieces */
   content: " [" attr(href) "] ";
   font-style:italic;
   color:#aaa;
}
      
      

CSS

CSS

Generated Elements - Attributes

<a href="http://google.com">Google</a>
a:hover:after
{
   color:#f00;
}
      
      

CSS

CSS

Generated Elements - Counters

CSS

CSS

Generated Elements - Counters

<ul>
   <li>Item</li>
   <li>Item</li>
   <li>Item</li>
</ul>
      
  • Item 1
  • Item 2
  • Item 3

CSS

CSS

Generated Elements - Counters

CSS counters are another option for CSS-generated content. Counters can be used to store a value and can be incremented or reset based on the number of times they're used in your page. To use counters, we'll have to rely on two additional CSS properites:

To use a counter, you first must 'reset' it to a value (0 by default). Once we have done so, we can use the counter in our content property. Additionally, we can increase the value of our counter by using the counter-increment property. By default, counters are incremented by 1, though we can specify any integer value if we'd like.

If we wanted to, we could use counters to replicate the mechanism used by browsers to provide numeric ordered lists (<ol>).

<ul>
   <li>Item</li>
   <li>Item</li>
   <li>Item</li>
</ul>
ul { list-style:none; counter-reset: listCounter; }/*** 'Reset' the counter named 'listCounter' to 0. ***/
li { counter-increment: listCounter; } /*** We increment the counter named 'listCounter' by 1 for every <li> element. ***/
li:before { content: counter(listCounter) ": "; }/*** We need to use a pseudo-element to actually display the counter value. ***/
      
  • Item 1
  • Item 2
  • Item 3

CSS

CSS

Generated Elements - Counters

By providing a value to our counter-reset property, we can specify what value our counter should be reset to. It is worth noting that counters are incremented before they are displayed in our pseudo-elements. That means that if we reset our counter to 5, the first list item will show '6' as the counter value.

<ul>
   <li>Item</li>
   <li>Item</li>
   <li>Item</li>
</ul>
ul { list-style:none; counter-reset: listCounter 5; }
li { counter-increment: listCounter; }
li:before { content: counter(listCounter) ": "; }
      
  • Item 1
  • Item 2
  • Item 3

CSS

CSS

Generated Elements - Counters

Similarly, we could increment our counter by more (or less) than 1. For example, we could increment by 2, resulting in an even-numbered list of items.

<ul>
   <li>Item</li>
   <li>Item</li>
   <li>Item</li>
</ul>
ul { list-style:none; counter-reset: listCounter; }
li { counter-increment: listCounter 2; }
li:before { content: counter(listCounter) ": "; }
      
  • Item 1
  • Item 2
  • Item 3

CSS

CSS

Generated Elements - Counters

Lastly, it is worth noting that we can pass an additional argument to the 'counter' function, specifying the style of the counter. This can be any of the styles allowed for the 'list-style-type' property.

<ul>
   <li>Item</li>
   <li>Item</li>
   <li>Item</li>
</ul>
ul { list-style:none; counter-reset: listCounter; }
li { counter-increment: listCounter 2; }
li:before { content: counter(listCounter, upper-roman) ": "; }
      
  • Item 1
  • Item 2
  • Item 3

CSS

CSS

Generated Elements - Counters

Using CSS counters isn't limited to HTML lists. For instance, imagine you're publishing a page containing the contents of a short book on HTML. The book, while short, does include a number of chapters and sections. You've already created the markup using the appropriate heading tags. However, you'd like to number each chapter/section without creating a maintenance nightmare in the future.

<h1>Introduction</h1>
   <h2>Conventions</h2>
   <h2>Source Code</h2>
   <h2>Errata</h2>
<h1>HTML</h1>
   <h2>Basic Text Formating</h2>
   <h2>Presentational Elements</h2>
   <h2>Phrase Elements</h2>

Ultimately, you'd like to have each chapter numbered, as well as each section underneath that chapter.

CSS

CSS

Generated Elements - Counters

This task can be completed easily by using two separate counters. The first counter, named 'chapter', is used for numbering our chapters. It is 'reset' to 0 on the body element. For each <h1>, we'll increment the 'chapter' counter by 1.

We'll also create a counter named 'section'. This counter will be 'reset' to 0 every time we come across an <h1> (i.e., a new chapter). We'll increment the 'section' counter by 1 for each <h2>.

body {
   counter-reset: chapter;
}
h1 {
   counter-increment: chapter;
   counter-reset: section;
}
h2 {
   counter-increment: section;
}
h1:before {
   content: "Chapter " counter(chapter) ": ";
}
h2:before {
   content: "Section " counter(chapter) "." counter(section) ": ";
}

The results can be seen on the next slide.

CSS

CSS

Generated Elements - Counters

      

Introduction

Conventions

Source Code

Errata

HTML

Basic Text Formating

Presentational Elements

Phrase Elements

While the output is exactly what we want, the practice of introducing multiple counters to accomplish this task doesn't scale well. For example, imagine if we had subsections as well, or even greater levels of heirarchy... Fortunately, there is a better option (see next slide).

CSS

CSS

Generated Elements - Counters

When we use the counter-reset property, a new counter is created. In the case of nested lists, a new counter (using the same counter name) is actually created for each nested list. CSS provides us with a means to take advantage of this fact!

In addition to the 'counter' function, we can also use the 'counters' function. The "counters" function allows us to use the nested counter as well as it's ancestors to create a heirarchy. Let's again look at the case of our online book. With multiple chapters, sections, and subsections, maintaining multiple counters simply isn't a great option.

<ol>
   <li>Chapter</li>
   <li>Chapter
      <ol>
         <li>Section</li>
         <li>Section</li>
         <li>Section
            <ol>
               <li>Subsection</li>
               <li>Subsection</li>
            </ol>
        </li>
      </ol>
   </li>
   <li>Chapter</li>
</ol>

CSS

CSS

Generated Elements - Counters

  1. Chapter
  2. Chapter
    1. Section
    2. Section
    3. Section
      1. Subsection
      2. Subsection
  3. Chapter

CSS

CSS

Generated Elements - Counters

Instead of using multiple counters, we'll use a single counter for our chapters, sections, and subsections. However, instead of using the "counter" function, we'll use the "counters" function, providing it with the name of our counter as well as the string that should be used to separate each value.

<ol>
   <li>Chapter</li>
   <li>Chapter
      <ol>
         <li>Section</li>
         <li>Section</li>
         <li>Section
            <ol>
               <li>Subsection</li>
               <li>Subsection</li>
            </ol>
        </li>
      </ol>
   </li>
   <li>Chapter</li>
</ol>
ol { list-style:none; counter-reset: listCounter; }
li { counter-increment: listCounter; }
li:before { content: counters(listCounter,".") ": "; }

Because we added a counter-reset property to our <ol> elements, a new counter is actually created for each of our nested lists. The value for each counter is then concatenated with "." to provide our CSS-generated content (see output on next slide).

CSS

CSS

Generated Elements - Counters

  1. Chapter
  2. Chapter
    1. Section
    2. Section
    3. Section
      1. Subsection
      2. Subsection
  3. Chapter

CSS

CSS

Review - Floating Issues

CSS

CSS

Floating Issues

For example, consider the following HTML code...


<div>
   <img src="cats.jpg" alt="CATS!" />
   <p>This is a picture of some cats.</p>
</div>

      
Non-floated image
This is a picture of some cats.

CSS

CSS

Floating Issues

img
{
   float:left;


}
      
Floated image
This is a picture of some cats.

CSS

CSS

Floating Issues

When we float the image left, the height of the containing element (<div>) shrinks to the size of the un-floated content.

img
{
   float:left;


}
      
Floated image
This is a picture of some cats.

CSS

CSS

Floating Issues

img { float:left; }

div { overflow:auto; }


      
Floated image
Applying 'overflow:auto' to the containing element will fix the float issue...

CSS

CSS

Floating Issues

CSS

CSS

Floating Issues

As previously discussed, floating an element that is the only child of it's parent will cause the parent element to collapse. During our lecture on the box model, we found that setting the parent element's overflow property to 'auto' would typically fix this issue. However, that technique isn't full-proof and sometimes leads to small scrollbars being displayed on the parent element!

During that same lecture, we also talked about the option of adding a <br /> element and setting it's clear property to 'both'. We didn't pursue this approach since it required us to add additional HTML elements to our page, purely for display purposes.

<div>
   <img src="cats.jpg" alt="CATS!" />
   <br style="clear:both" /> <!-- Not great... -->
</div>


      
Non-floated image

That said, the approach of using a <br /> was tempting, as it worked across browsers and didn't have the issue of scrollbars that came with our 'overflow:auto' solution. While adding an element in our HTML file isn't a great solution, we can now use CSS-generated content to provide a more robust solution to the float/collapse issue.

CSS

CSS

CSS Generated Content - Clear Fix

<div class='clearFix'>
   <img src="cats.jpg" alt="CATS!" />
   <!-- <br style="clear:both" /> -->
</div>
      
Non-floated image

CSS

CSS

CSS Generated Content - Clear Fix

First, we'll use a class called 'clearFix' for our parent element.

<div class='clearFix'>
   <img src="cats.jpg" alt="CATS!" />
   <!-- <br style="clear:both" /> -->
</div>

Next, we'll use our CSS pseudo-element for ':after' to create a new inline (by default) child of the <div>.

.clearFix:after
{
   content: ' ';
   display: block;
   clear: both;
   visibility: hidden;
   font-size: 0;
   height: 0;
}

Note that we still provided a content property, even though there is no content to be displayed. If we were to leave that out, the rule would be ignored completely.

Additionally, we specified that the pseudo-element should display as a block element, that it should be hidden, that it's height should be 0, and that the font-size should be 0. Most of these properties are set to ensure that the pseudo element isn't actually visible to users. Most importantly, we set the clear property to 'both'. This will ensure that even if every element inside of the <div> is floated to the left or right, the div will still stretch to contain all of them.

      
Non-floated image

CSS

CSS

Review - Rounded Corners

Rounded Corners

CSS

CSS

Review - Rounded Corners

You may remember, during our lecture on background images, that we discussed creating the effect of 'rounded corners'.

Rounded Corners

In order to do this, we had to use multiple nested <div> elements.

<div id="contentTop">
   <div id="contentBottom">
      <div id="content">
         This is some content.
      </div>
   </div>
</div>

However, using CSS-generated content, we can now do this with less HTML markup.

CSS

CSS

Review - Rounded Corners

CSS

CSS

Generated Elements - Rounded Corners

<div id="rounded">
   This is some content.
</div>

CSS

CSS

Generated Elements - Rounded Corners

.rounded {
   width:343px;
   padding:10px;
   background-color:white;
   border:5px solid #597CBB;
   margin-top:5%;

   position:relative;
}

CSS

CSS

Generated Elements - Rounded Corners

First, we'll create a single <div> element.

<div id="rounded">
   This is some content.
</div>

Next, we'll set some CSS properties for the <div>, giving it a fixed width as well as some padding, borders, and a top margin. Also, note that we set the position property of the element to 'relative'!

.rounded {
   width:343px;
   padding:10px;
   background-color:white;
   border:5px solid #597CBB;
   margin-top:5%;

   position:relative;
}

We can now create two pseudo-elements for the <div> (:before and :after). Each of these will have a specific background image that will provide two of the rounded corners.

We'll position each of the pseudo-elements absolutely. Because we specified that the parent element was positioned 'relative', it is the containing element for the pseudo elements.

.rounded:before {
   content:url("../images/topRounded.png");
   position:absolute;
   height:30px;
   top:-30px;
   left:-10px;
}

.rounded:after {
   content:url("../images/bottomRounded.png");
   position:absolute;
   height:66px;
   top:100%;
   left:-10px;
}

Using the 'top' and 'left' properties to position the pseudo-elements (with their rounded corner background images) in the correct location, we've given the impression that the <div> itself has rounded corners. The output can be seen on the next slide.

CSS

CSS

Generated Elements - Rounded Corners

      
This is some content.

CSS

CSS

Generated Elements - Shapes

border:100px solid #000;
border-color: red green blue orange;

width:0;
height:0;

CSS

CSS

Generated Elements - Shapes

We can also use CSS-generated content to make useful shapes which can be incorporated into our site design. Before we jump into that, let's review a little bit about our box model and, in particular, how borders are rendered.

Consider the following: An element is given an explicit height of 0 pixels and an explicit width of 0 pixels. It is effectively non-existent to the viewer. However, if we were to add a 100 pixel border to the element, it's true dimensions would be 200 × 200 pixels. If we applied a different color to each border, we could see exactly how the browser renders each one.

border:100px solid #000;
border-color: red green blue orange;

width:0;
height:0;
      

When an element is 0 × 0 pixels tall, all four borders are drawn as triangles, their apexes meeting in the middle. If we experiment with the size of our borders, we'll find that we can manipulate how these triangles are drawn. Additionally, we don't have to display all of these borders if we change their color to 'transparent'. This opens up a number of options for us to play with.

CSS

CSS

Generated Elements - Shapes

border:100px solid #000;
border-color: red green blue orange;
border-width: 130px 50px 70px 150px;
width:0;
height:0;
      

CSS

CSS

Generated Elements - Shapes

border:100px solid #000;
border-color: transparent red transparent transparent;
width:0;
height:0;

CSS

CSS

Generated Elements - Shapes

border:100px solid #000;
border-color: transparent red transparent transparent;
width:0;
height:0;
      

CSS

CSS

Generated Elements - Shapes

border:100px solid #000;
border-color: red red transparent transparent;
width:0;
height:0;
      

CSS

CSS

Generated Elements - Shapes

border:100px solid #000;
border-color: transparent red;
width:0;
height:0;
      

CSS

CSS

Generated Elements - Speech Bubble

<div class="speechBubble">
   "CSS dynamic shapes are awesome!"
</div>

CSS

CSS

Generated Elements - Speech Bubble

Consider the following HTML snippet:

<div class="speechBubble">
   "CSS dynamic shapes are awesome!"
</div>
      
"CSS dynamic shapes are awesome!"

The output, while perfectly fine, isn't anything spectacular. To add a little flare to it, we'd like to add a small triangle at the bottom of the <div>, making it look more like a "speech bubble" as is often used in comic books and other similar formats.

CSS

CSS

Generated Elements - Speech Bubble

.speechBubble
{
   background-color:#597CBB;
   position:relative;
   min-height:20px;
}

.speechBubble:before
{
   content: "";
   position:absolute;
   right:20px;
   top:100%;
   width:0;
   height:0;
   border:20px solid #597CBB;
   border-color: #597CBB transparent transparent transparent;
}

CSS

CSS

Generated Elements - Speech Bubble

We can use pseudo-elements to create an additional element which can then be positioned absolutely to give us the effect we're looking for.

.speechBubble
{
   background-color:#597CBB;
   position:relative;
   min-height:20px;
}

We'll set our parent element to be positioned relatively, making it the containing element for it's absolutely positioned descendants. For our pseudo-element, we could use a background image to get our small triangle. However, this requires an additional HTTP request to download the image. Additionally, image colors sometimes don't match those rendered by the browser. Instead of using an image, we'll use CSS borders to create our triangle decoration.

.speechBubble:before
{
   content: "";
   position:absolute;
   right:20px;
   top:100%;
   width:0;
   height:0;
   border:20px solid #597CBB;
   border-color: #597CBB transparent transparent transparent;
}
      
"CSS dynamic shapes are awesome!"

CSS

CSS

Generated Elements - CSS Ribbon

<div class="ribbon">
   <h1>Page Header</h1>
</div>

CSS

CSS

Generated Elements - CSS Ribbon

Next, let's consider the following HTML snippet:

<div class="ribbon">
   <h1>Page Header</h1>
</div>
      

Page Header

We have a page heading that is pretty plain. We'd like to spruce it up by making it look like a ribbon wrapping around the parent div.

CSS

CSS

Generated Elements - CSS Ribbon

.ribbon h1
{
   background-color:#597CBB;

   position:relative;
   min-height:30px;
   margin:2% -30px;
}

CSS

CSS

Generated Elements - CSS Ribbon

.ribbon h1:before,
.ribbon h1:after
{
   content: "";
   width:0;
   height:0;
   border-style:solid;
   border-color: transparent #142E5B;
   position:absolute;
   top:100%;
}

CSS

CSS

Generated Elements - CSS Ribbon

We'll start by giving the heading a background color, a minimum height, and positioning it relatively (so it is the containing element of any absolutely positioned descendants). Lastly, we'll give the heading a top and bottom margin of 2% and a left and right margin of negative 30 pixels!

.ribbon h1
{
   background-color:#597CBB;

   position:relative;
   min-height:30px;
   margin:2% -30px;
}

Next, we'll create our pseudo-elements. The goal is to create two small triangles that will sit just below our header, filling in the 30 pixel spaces on the left and right. To create these triangles, we'll once again use CSS borders. Because both elements share the same border style and color, we'll specify those here. We'll also position both absolutely, 100% down from the top of the containing element (the <h1>).

.ribbon h1:before,
.ribbon h1:after
{
   content: "";
   width:0;
   height:0;
   border-style:solid;
   border-color: transparent #142E5B;
   position:absolute;
   top:100%;
}

Lastly, we'll create our two triangles and position them to the left and right respectively.

.ribbon h1:before
{
   right:0;
   border-width: 0 0 30px 30px;
}

div.ribbon h1:after
{
   left:0;
   border-width: 0 30px 30px 0;
}

The results can be seen on the next slide.

CSS

CSS

Generated Elements - CSS Ribbon

      

Page Header

Our page header now has a unique look and feel, giving it some distinction on the page. Because this was implemented only using CSS, it will load very quickly in the browser without using much processing power or additional HTTP requests.

CSS

CSS

Generated Elements - Page Fold

<div class="folded">
   This is my content.
</div>

CSS

CSS

Generated Elements - Page Fold

Lastly, we'll consider the following HTML snippet:

<div class="folded">
   This is my content.
</div>
      
This is my content.

Again, nothing too fancy. Just some plain text in a <div>. To enhance the display of this content, we want to make it look like one corner of the page is folded over.

CSS

CSS

Generated Elements - Page Fold

.folded
{
   padding-top:40px;
   padding-right:40px;
   background-color:#96c02e;
   position:relative;
}

.folded:after
{
   content:"";
   width:0px;
   height:0px;
   position:absolute;
   right:0;
   top:0;
   border:30px solid #638f14;
   border-color: #fff #fff #638f14 #638f14;
}

CSS

CSS

Generated Elements - Page Fold

Similar to our previous examples, we'll start by formatting the element itself. We give our <div> some padding, set the background color, and specify that it should be positioned relatively.

.folded
{
   padding-top:40px;
   padding-right:40px;
   background-color:#96c02e;
   position:relative;
}

Next, we'll create a single pseudo-element and position it absolutely in the top right corner of the containing element. Lastly, we'll create a triangle shape using CSS borders. It's important to note that while the shape appears to be a triangle, we've actually just matched the background color of the parent's parent element.

.folded:after
{
   content:"";
   width:0px;
   height:0px;
   position:absolute;
   right:0;
   top:0;
   border:30px solid #638f14;
   border-color: #fff #fff #638f14 #638f14;
}

The result is a page that looks as though the corner has been folded over.

      
This is my content.

CSS

CSS

Example - ISTA Bistro

Site without CSS

CSS

CSS

Example - ISTA Bistro

Site using CSS generated elements

CSS

CSS

Reminders