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.
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.
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 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
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
There are variants of the BNF used today, such as “Extended Backus–Naur Form” (EBNF) and “Augmented Backus–Naur Form” (ABNF).
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.
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
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>
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 values can be arranged into property value combinators using the following methods:
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;
}
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 ]
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
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>
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 values can also be multiplied using the following methods:
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; }
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
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
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>; }
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>; }
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
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
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; }
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.
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;
}
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:
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;
}
Site Twitter Github Slideshare Linkedin