214-01

CSS property value syntax

Slide instructions

SPACEBAR to move forward through slides.

SHIFT & SPACEBAR to move backwards through slides.

LEFT ARROW & RIGHT ARROW to move through sections.

ESC to see overview and ESC again to exit.

F to enter presentation mode and ESC to exit.

Introduction

This slide deck will give you a basic understanding of the W3C property/value syntax.

This will help you understand the various W3C CSS Specifications.

Backus-Naur Form

Let’s start with a quick look at Backus-Naur Form, as this will help to explain the CSS property value syntax.

In computer science, Backus–Naur Form (BNF) is one of the main notation techniques used to describe the syntax of computing languages.

A Backus-Naur Form specification is a set of derivation rules, written as:


// BNF Syntax example
<symbol> ::= __expression__

At the left, there is a “non-terminal symbol”.


// BNF Syntax example
<symbol> ::= __expression__

After this is a symbol that means “may be replaced with”.


// BNF Syntax example
<symbol> ::= __expression__

And at the right is an “expression”.


// BNF Syntax example
<symbol> ::= __expression__

The __expression__ consists of one or more sequences of symbols that are used to derive the meaning of the symbol on the left.

Backus-Naur specifications are basically saying: “Whatever is on the left may be replaced with whatever is on the right”.

Non-terminal symbols

Non-terminal symbols appear between angle brackets "< >". These symbols can be broken down or replaced further.

For example, in the following example, the <digit> non-terminal symbol can be broken down further.


/* Non-terminal symbols */
<integer> ::= <digit> | <digit><integer>

<digit> ::=
  0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

Terminal symbols

A terminal symbol indicates that the value cannot be broken down or replaced further.

In the following example, the digits cannot be broken down further.


<digit> ::=
  0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

Variations of BNF

There are variants of the BNF used today, such as “Extended Backus–Naur Form” (EBNF) and “Augmented Backus–Naur Form” (ABNF).

The CSS Property Value Syntax

While the W3C CSS property value syntax has some similarities to BNF and EBNF, it also has some differences.

Like BNF and EBNF, it begins with a non-terminal symbol.


/* Non-terminal symbol */
<line-width> =
  <length> | thin | medium | thick

Like EBNF, it uses an equals "=" after the initial non-terminal symbol. This also means “may be replaced with”.


/* Equals symbol */
<line-width> =
  <length> | thin | medium | thick

However, unlike BNF and EBNF, the CSS property value syntax describes symbols as “component values”.


/* Component values */
<line-width> =
  <length> | thin | medium | thick

There are three different types of component values.

1. Keyword values

These values appear without quotes or angle brackets. They are used “as is” as property values.

As they cannot be replaced or broken down further, they are terminal.


/* Keyword value examples */
<line-width> =
  <length> | thin | medium | thick

2. Property data types

These types define the actual property name.

They are defined using the property name (complete with single quotes) between the angle brackets "< >". They are non-terminal.


/* Property data type example */
<'border'> =
  <line-width> || <line-style> || <color>

3. Non-property data types

These are non-terminal data types that are used to help define property data types.

For example, <line-width> is not a property, but it helps to define the various <border> properties.


/* Non-property data type */
<line-width> =
  <length> | thin | medium | thick

/* Property syntax */
<'border-width'> =
  <line-width>{1,4}

How do you identify the difference between property and non-property data types?

Property data types contain single quotes around the name.


/* Property data type */
<'border'>

/* Non-property data type */
<line-width>

There are some property and non-property data types that share the same name.

For example, the <'color'> property data type and <color> non-property data type share the same name.


/* Property data type */
<'color'>

/* Non-property data type */
<color>

This allows the non-property data type to be used where ever that value needs to be defined.


/* The color non-property data type */
<'color'> = <color>
<'background-color'> = <color>
<'border-color'> = <color>

Component value combinators

Component values can be arranged into property value combinators using the following methods:

1. Any order

Component values written directly after each other means that all of them must occur, in the given order.


/* Component arrangement */
<property> = value1 value2 value3

/* Example */
.example {
  property: value1 value2 value3; 
}

2. Double ampersand

A double ampersand "&&" separating two or more components means that all of them must occur, in any order.


/* Component arrangement */
<property> = value1 && value2

/* Examples */
.example { property: value1 value2; }
.example { property: value2 value1; }

/* Real-world example */
<'text-emphasis-position'> =
  [ over | under ] && [ right | left ]

3. Single pipe

A single pipe "|" separates two or more alternatives means that only one of them must occur.


/* Component arrangement */
<property> = value1 | value2 | value3

/* Examples */
.example {  property: value1; }
.example { property: value2; }
.example { property: value3; }

/* Real world example */
<attachment> =
  scroll | fixed | local

4. Double pipe

A double pipe "||" separating two or more options means that one or more of them must occur, in any order.


/* Component arrangement */
<property> = value1 || value2 || value3

/* Examples */
.example { property: value1; }
.example { property: value2; }
.example { property: value3; }
.example { property: value1 value2; }
...etc

<'border'> = 
  <line-width> || <line-style> || <color>

5. Square brackets

Square brackets "[ ]" surrounding two or more alternatives means that the components inside are a single grouping.


/* Component arrangement */
<property> = [ value1 | value2 ] value3

/* Examples */
.example { property: value1 value3; }
.example { property: value2 value3; }

<'border-radius'> =
  <length-percentage>{1,4}
  [ / <length-percentage>{1,4} ]?

Component value multipliers

Component values can also be multiplied using the following methods:

1. Question mark

A question mark "?" indicates that the preceding type, word, or group is optional and occurs zero or one times.


/* Component multiplier */
<property> = value1 [, value2 ]?

/* Examples */
.example { property: value1; }
.example { property: value1, value2; }

2. An asterisk

An asterisk "*" indicates that the preceding type, word, or group occurs zero or more times.


/* Component multiplier */
<property> = value1 [, <value2> ]*

/* Examples */
.example { property: value1; }
.example { property: value1, <value2>; }
.example {
  property: value1, <value2>, <value2>; }
...etc

3. A plus symbol

A plus "+" indicates that the preceding type, word, or group occurs one or more times.


/* Component multiplier */
<property> = <value>+

/* Examples */
.example { property: <value>; }
.example { property: <value> <value>; }
.example {
  property: <value> <value> <value>; }
...etc

4. A single number in curly braces

A single number in curly braces "{A}" indicates that the preceding type, word, or group occurs "A" times.


/* Component multiplier */
<property> = <value>{2}

/* Examples */
.example { property: <value> <value>; }

5. A comma-separated pair of numbers

A comma-separated pair of numbers in curly braces "{A,B}" indicates that the preceding type, word, or group occurs at least "A" and at most "B" times.


/* Component multiplier */
<property> = <value>{1,3}

/* Examples */
.example { property: <value>; }
.example { property: <value> <value>; }
.example {
  property: <value> <value> <value>; }

6. The “B” may be omitted

The "B" may be omitted "{A,}" to indicate that there must be at least "A" repetitions, with no upper limit on the number of repetitions.


/* Component multiplier */
<property> = <value>{1,}

/* Examples */
.example { property: <value>; }
.example { property: <value> <value>; }
.example {
  property: <value> <value> <value>; }
...etc

7. A hash

A hash "#" indicates that the preceding type, word, or group occurs one or more times, separated by comma tokens. (Whitespace is optional)


/* Component multiplier */
<property> = <value>#

/* Examples */
.example { property: <value>; }
.example { property: <value>, <value>; }
.example {
  property: <value>, <value>, <value>; }
...etc

8. An exclamation point

An exclamation point "!" after a group indicates that the group is required and must produce at least one value.


/* Component multiplier */
<property> = value1 [ value2 | value3 ]!

/* Examples */
.example { property: value1 value2; }
.example { property: value1 value3; }

Combining multipliers

Each of these multipliers can be used in combination with other multipliers to refine the outcome.

For example the rgb() non-property data type uses the following multipliers:


rgb() =
  rgb( <rgb-component>#{3} )

This means that there must be three instances of the <rgb-component> value, and these three instances must be comma-separated.

An example

Let’s look at the <'text-shadow'> property as an example.


/* text-shadow */
<'text-shadow'> =
  none | [ <length>{2,3} && <color>? ]#

This can be broken down to:


/* text-shadow */
<'text-shadow'> =
  none | [ <length>{2,3} && <color>? ]#

/* Explanation */
None OR

/* text-shadow */
<'text-shadow'> =
  none | [ <length>{2,3} && <color>? ]#

/* Explanation */
Two or three length values

/* text-shadow */
<'text-shadow'> =
  none | [ <length>{2,3} && <color>? ]#

/* Explanation */
And zero or one color value

/* text-shadow */
<'text-shadow'> =
  none | [ <length>{2,3} && <color>? ]#

/* Explanation */
In any order

/* text-shadow */
<'text-shadow'> =
  none | [ <length>{2,3} && <color>? ]#

/* Explanation */
There can be one or more text-shadow
separated by commas

This would allow a wide range of options such as:


/* None */
.example {
  text-shadow: none; 
}

/* 2 lengths values */
.example {
  text-shadow: 10px 10px; 
}

/* 3 length values */
.example {
  text-shadow: 10px 10px 10px;
}

/* 3 length values + color */
.example {
  text-shadow: 10px 10px 10px red;
}

/* In any order */
.example {
  text-shadow: red 10px 10px 10px; 
}

/* Multiple text-shadows */
.example {
  text-shadow: 
    10px 10px red,
    lime 20px 20px 30px;
}

Exercise 1: Write the syntax for a burger

How would you define the syntax of a burger if you had to use a specific set of ingredients in a specific order?

Write the syntax for the burger, in the correct order from bottom to the top of the bun. The ingredients are:

  • bottom bun
  • 1 of the following: mustard or mayonnaise
  • lettuce (optional)
  • tomato (optional)
  • 1 of the following meats: chicken or beef
  • 1 to 3 slices of the following cheese: swiss or cheddar
  • 1 of the following sauces: tomato or bbq
  • top bun

Answer

Step 1: Define the property data type:


<'burger'> =

Step 2: Add bottom bun - written as bottom-bun keyword:


<'burger'> =
  bottom-bun

Step 3: Add 1 of the following: mustard or mayonnaise:


<'burger'> =
  bottom-bun
  [ mustard | mayonnaise ]

Step 4: Add lettuce (optional):


<'burger'> =
  bottom-bun
  [ mustard | mayonnaise ]
  lettuce?

Step 5: Add tomato (optional):


<'burger'> =
  bottom-bun
  [ mustard | mayonnaise ]
  lettuce?
  tomato?

Step 6: Add 1 of the following meats: chicken or beef:


<'burger'> =
  bottom-bun
  [ mustard | mayonnaise ]
  lettuce?
  tomato?
  [ chicken | beef ]

Step 7: Add 1 to 3 slices of the following cheese: swiss-cheese or cheddar-cheese:


<'burger'> =
  bottom-bun
  [ mustard | mayonnaise ]
  lettuce?
  tomato?
  [ chicken | beef ]
  [ swiss-cheese | cheddar-cheese ]{1,3}

Step 8: Add 1 of the following sauces: tomato-sauce or bbq-sauce:


<'burger'> =
  bottom-bun
  [ mustard | mayonnaise ]
  lettuce?
  tomato?
  [ chicken | beef ]
  [ swiss-cheese | cheddar-cheese ]{1,3}
  [ tomato-sauce | bbq-sauce]

Step 9: Add top bun - written as top-bun keyword:


<'burger'> =
  bottom-bun
  [ mustard | mayonnaise ]
  lettuce?
  tomato?
  [ chicken | beef ]
  [ swiss-cheese | cheddar-cheese ]{1,3}
  [ tomato-sauce | bbq-sauce]
  top-bun

If this <burger> property were to be used in CSS, the result could be something like:


.myburger {
  burger:
    bottom-bun
    mustard
    lettuce
    chicken
    swiss-cheese
    tomato-sauce
    top-bun;
}

Russ Weakley

Site Twitter Github Slideshare Linkedin

Next deck

214-02: Property - color