How to create a test for the W3C CSS Test Suite

How to create a test for the W3C CSS Test Suite

A simple demo that shows how to create a CSS test for the W3C CSS Test Suite.

In this article I'll explain how to build a test on a CSS feature for the W3C CSS Test Suite. The test will focus on the box model.

The markup

When providing a test that will be used by browsers vendors, there are some simple rules to follow before writing down our markup. Let's start by viewing a prototype of a test page.


<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>CSS 2.1 Test Suite: Acid Test on the box model </title>
<link rel="author" title="Gabriele Romanato" href="mailto:gabriele.romanato@gmail.com"/>
<link rel="help" href="http://www.w3.org/TR/CSS21/box.html"/>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="flags" content="Valid" />
<meta name="assert" content="UA should support the specified properties"/>
<style type="text/css" media="screen">
</style>
</head>

Some considerations:

  1. The markup must be valid and should have an XML prolog.
  2. The title of the page should be self-evident and clear.
  3. The link elements must provide two kinds of information:
    1. the author of the test (email or contact page)
    2. the relevant section of the specifications that's being tested.
  4. The meta elements must provide two kinds of information:
    1. the type of the test (Flags)
    2. what User-Agents (browsers) must do to pass the test (Assert).
  5. The relevant styles should be embedded in the page itself.

Furhermore, the test should be provided in two different formats: application/xhtml+xml (XHTML 1.1) and text/html (XHTML 1.0).

What we want to achieve

We want to draw a smiling face with the only aid of the box model CSS properties.

Positioning and initial formatting of the face

Our image is virtually divided into 15 rows, since its original dimensions are 150 x 150 pixels. So we're going to format one row per time, after setting the global dimensions of the main container.


#face {
	font-size: 10px;
	width: 15em;
	margin: 2em auto;
	background: white;
	color: black;
}
.row {
	margin: 0;
}

The top of the face

Since we're working with the box model, we won't use any declaration of width or height. Instead, we'll use only margins, padding, and borders to create our face. Here are the first styles:


#top {
	margin-left: 5em;
	margin-right: 5em;
	background: black;
	padding: 0.5em 0;
}

Our box will have a width of 5em, since it has its horizontal margins set to 5em (so 15em - 5em - 5em = 5em). Since we don't use an explicit height here, we have to set some vertical padding to make the background color appear. Our rows should be 1em high, so we set the vertical padding to 0.5em.

The forehead of the face

The following three boxes draw the forehead of our face.


#forehead-1 {
	margin-left: 3em;
	margin-right: 3em;
	background: yellow;
	padding: 0.5em 0;
	border-left: 2em solid black;
	border-right: 2em solid black;
}

#forehead-2 {
	margin-left: 2em;
	margin-right: 2em;
	background: yellow;
	padding: 0.5em 0;
	border-left: 1em solid black;
	border-right: 1em solid black;
}

#forehead-3 {
	margin-left: 1em;
	margin-right: 1em;
	background: yellow;
	padding: 0.5em 0;
	border-left: 1em solid black;
	border-right: 1em solid black;
}

The technique is very similar to the one above. The only difference here is that we've used horizontal borders to draw the outline of the face.

The eyes

The styles for the eyes allows us to use also negative margins, as shown below.


#forehead-4 {
	margin-left: 1em;
	margin-right: 1em;
	background: yellow;
	padding: 0.5em 0;
	border-left: 1em solid black;
	border-right: 1em solid black;
}

#eyes-1 {
	margin-left: 2em;
	margin-right: 2em;
	border-left: 2em solid black;
	border-right: 2em solid black;
	padding: 0.5em 0;
}

#head-1 {
	background: yellow;
	padding: 0.5em 0;
	border-left: 1em solid black;
	border-right: 1em solid black;
}

#eyes-2 {
	margin-left: 3em;
	margin-right: 3em;
	border-left: 2em solid black;
	border-right: 2em solid black;
	padding: 0.5em 0;
	margin-top: -1em;
}

We've used a negative top margin to fix a side effect of the vertical padding used on each element. In fact, since the box that draws the second row of the eyes is contained inside another element, we have a gap of 1em, that is, the sum of the padding of the parent and its in-flow child. The rest of the CSS code is practically identical to the above rules.

[view-example url="http://codepen.io/gabrieleromanato/pen/mGwpn"]