Understanding the mysteries of the CSS property value syntax

90
syntax. Understanding the mysteries of the CSS property value

Transcript of Understanding the mysteries of the CSS property value syntax

syntax.Understanding the mysteries of the CSSproperty value

The W3C uses a specific syntax for defining CSS property values.

/*  CSS  property  value  syntax  examples  */  

<line-­‐width>  =  <length>  |  thin  |  medium  |  thick  

<bg-­‐size>  =  [  <length>  |  <percentage>  |  auto  ]{1,2}  |  cover  |  contain  

<'background'>  =  [  <bg-­‐layer>  ,  ]*  <final-­‐bg-­‐layer>  

<'border-­‐image-­‐slice'>  =  [<number>  |  <percentage>]{1,4}  &&  fill?

The aim of this presentation is to give you a basic understanding of this syntax to help understand

the various W3C CSS Specifications.

We’re going to start with a quick look at Backus-Naur Form, as this will help to explain the CSS

property value syntax.

Backus-Naur Form

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__

//  BNF  Syntax  example  

<symbol>  ::=  __expression__

Non-terminal Symbol

//  BNF  Syntax  example  

<symbol>  ::=  __expression__

“May be replaced with”

//  BNF  Syntax  example  

<symbol>  ::=  __expression__

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 “<  >”. Non-terminal symbols can be

broken down or replaced further.

/*  Non-­‐terminal  symbols  -­‐  recursive  example  */  

<integer>  ::=  <digit>  |  <digit><integer>  

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

Non-terminal symbols

A terminal symbol indicates that the value cannot be broken down

or replaced further.

/*  Non-­‐terminal  symbols  -­‐  recursive  example  */  

<integer>  ::=  <digit>  |  <digit><integer>  

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

Terminal Symbols

There are variants of the BNF used today, such as

Extended Backus–Naur Form (EBNF)

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

Non-terminal symbol

Like EBNF, it uses an equals “=” after the initial non-terminal

symbol. This also means “may be replaced with”.

/*  The  equals  sign  */  

<line-­‐width>  =  <length>  |  thin  |  medium  |  thick

The “=” symbol

However, unlike BNF and EBNF, the CSS property value syntax

describes symbols as “component values”.

/*  Component  values  */  

<line-­‐width>  =  <length>  |  thin  |  medium  |  thick

Component values

There are four different types of component values.

1. Keyword valuesThese 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  example  */  

<line-­‐width>  =  <length>  |  thin  |  medium  |  thick

Keyword Value

2. Basic data typesThese basic data types define

core values such as <length> and <color>. They are non-terminal as they can be replaced with actual

length or color values.

/*  Basic  data  type  example  */  

<'background-­‐color'>  =  <color>

Basic Data Type

For example, the “<color>” symbol indicates that this value can be replaced with a value

such as:

/*  Basic  data  type  example  */  

.example  {  background-­‐color:  honeydew;  }  

.example  {  background-­‐color:  rgb(50%,50%,50%);  }  

.example  {  background-­‐color:  rgba(100%,100%,100%,.5);  }  

.example  {  background-­‐color:  hsl(280,100%,50%);  }  

.example  {  background-­‐color:  hsla(280,100%,50%,0.5);  }  

.example  {  background-­‐color:  transparent;  }

3. Property data typesThese types define the property

name. They are defined using the property name (complete with

quotes) between the angle brackets “<  >”. They are non-

terminal.

/*  Property  data  type  example  */  

<'border-­‐width'>  =  <line-­‐width>{1,4}

Property Data Type

4. Non-property data typesThese types do not share the

same name as a property. However, they help define aspects

of specific properties. They are non-terminal.

For example, <line-­‐width> is not a property, but it is a data type that

helps to define the various <border> properties.

/*  Non-­‐property  data  type  example  */  

<line-­‐width>  =  <length>  |  thin  |  medium  |  thick

Not a property

/*  Non-­‐property  data  type  example  */  

<line-­‐width>  =  <length>  |  thin  |  medium  |  thick    

<'border-­‐width'>  =  <line-­‐width>{1,4}

Helps define a property

A recap of the four different types of component values?

/*  Four  different  types  */  

thin  

<color>  

<‘border-­‐width'>  

<line-­‐width>

Keyword Value

Basic Data Type

Property Data Type

Non-property Data Type

Component value

combinators

Component values can be arranged into property value

combinators using the following methods:

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

the given order.

/*  Component  arrangement  -­‐  all  in  given  order  */  

<property>  =  value1  value2  value3  

/*  Example  */  

.example  {  property:  value1  value2  value3;  }  

2. A double ampersand “&&” separating two or more

components means that all of them must occur, in any order.

/*  Component  arrangement  -­‐  all  in  any  order  */  

<property>  =  value1  &&  value2  

/*  Examples  */  

.example  {  property:  value1  value2;  }  

.example  {  property:  value2  value1;  }

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

This symbol acts as “OR”.

/*  Component  arrangement-­‐  one  of  them  must  occur  */  

<property>  =  value1  |  value2  |  value3  

/*  Examples  */  

.example  {  property:  value1;  }  

.example  {  property:  value2;  }  

.example  {  property:  value3;  }  

4. A double pipe “||” separating two or more options means that

one or more of them must occur, in any order.

/*  Component  arrangement-­‐  one  or  more  in  any  order  */  

<property>  =  value1  ||  value2  ||  value3  

/*  Examples  */  

.example  {  property:  value1;  }  

.example  {  property:  value2;  }  

.example  {  property:  value3;  }  

.example  {  property:  value1  value2;  }  

.example  {  property:  value1  value2  value3;  }  

...etc

5. Square brackets “[  ]” surrounding two or more

alternatives means that the components inside are a single

grouping.

/*  Component  arrangement-­‐  a  single  grouping  */  

<property>  =  [  value1  |  value2  ]  value3  

/*  Examples  */  

.example  {  property:  value1  value3;  }  

.example  {  property:  value2  value3;  }

A recap of the component value combinators:

/*  All  in  given  order  */  <property>  =  value1  value2  value3  

/*  All  in  any  order  */  <property>  =  value1  &&  value2  

/*  One  of  them  must  occur  */  <property>  =  value1  |  value2  

/*  One  or  more  in  any  order  */  <property>  =  value1  ||  value2  

/*  A  single  grouping  */  <property>  =  [  value1  |  value2  ]  

Component value multipliers

Component values can also be multiplied using the following

methods:

1. A question mark “?” indicates that the preceding type, word, or group is optional and occurs zero

or one times.

/*  Component  multiplier  -­‐  zero  or  one  time  */  

<property>  =  value1  [,  value2  ]?  

/*  Examples  */  

.example  {  property:  value1;  }  

.example  {  property:  value1,  value2;  }

2. An asterisk “*” indicates that the preceding type, word, or group

occurs zero or more times.

/*  Component  multiplier  -­‐  zero  or  more  times  */  

<property>  =  value1  [,  <value2>  ]*  

/*  Examples  */  

.example  {  property:  value1;  }  

.example  {  property:  value1,  <value2>;  }  

.example  {  property:  value1,  <value2>,  <value2>;  }  

.example  {  property:  value1,  <value2>,  <value2>,  <value2>;  }  

...etc

3. A plus “+” indicates that the preceding type, word, or group

occurs one or more times.

/*  Component  multiplier  -­‐  one  or  more  times  */  

<property>  =  <value>+  

/*  Examples  */  

.example  {  property:  <value>;  }  

.example  {  property:  <value>  <value>;  }  

.example  {  property:  <value>  <value>  <value>;  }  

...etc

4. A single number in curly braces “{A}” indicates that the preceding type, word, or group occurs “A”

times.

/*  Component  multiplier  -­‐  occurs  A  times  */  

<property>  =  <value>{2}  

/*  Examples  */  

.example  {  property:  <value>  <value>;  }

5. 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  -­‐  at  least  A  and  at  most  B  */  

<property>  =  <value>{1,3}  

/*  Examples  */  

.example  {  property:  <value>;  }  

.example  {  property:  <value>  <value>;  }  

.example  {  property:  <value>  <value>  <value>;  }

6. 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  -­‐  at  least  A,  no  upper  limit  */  

<property>  =  <value>{1,}  

/*  Examples  */  

.example  {  property:  <value>;  }  

.example  {  property:  <value>  <value>;  }  

.example  {  property:  <value>  <value>  <value>;  }  

...etc

7. A hash “#” indicates that the preceding type, word, or group

occurs one or more times, separated by comma tokens.

(Whitespace is optional)

/*  Component  multiplier  -­‐  one  or  more,  separated  by  commas  */  

<property>  =  <value>#  

/*  Examples  */  

.example  {  property:  <value>;  }  

.example  {  property:  <value>,  <value>;  }  

.example  {  property:  <value>,  <value>,  <value>;  }  

...etc

8. An exclamation point “!” after a group indicates that the group is required and must produce at

least one value.

/*  Component  multiplier  -­‐  required  group,  at  lease  one  value  */  

<property>  =  value1  [  value2  |  value3  ]!  

/*  Examples  */  

.example  {  property:  value1  value2;  }  

.example  {  property:  value1  value3;  }

A recap of component value multipliers:

?  

*  

+  

{A}  

{A,B}  

{A,}  

#  

!

/*  zero  or  one  time  */  

/*  zero  or  more  times  */  

/*  one  or  more  times  */  

/*  occurs  A  times  */  

/*  at  least  A  and  at  most  B  */  

/*  at  least  A,  no  upper  limit  */  

/*  one  or  more,  separated  by  commas  */  

/*  at  lease  one  value  from  the  group  */

An example?

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

/*  text-­‐shadow  */  

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

/*  text-­‐shadow  */  

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

/*    |  =  One  of  them  must  occur  #  =  one  or  more,  separated  by  commas  &&  =  All  in  any  order  */  ?  =  zero  or  one  time  */  */  

.example  {  text-­‐shadow:  none  OR  one  or  more  comma-­‐separated  groups  of  2-­‐3  length  values  and  optional  color  value  in  any  order;  }

/*  text-­‐shadow  */  

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

/*  Examples  */  

.example  {  text-­‐shadow:  none;  }  

.example  {  text-­‐shadow:  10px  10px;  }  

.example  {  text-­‐shadow:  10px  10px  10px;  }  

.example  {  text-­‐shadow:  10px  10px  10px  red;  }  

.example  {  text-­‐shadow:  red  10px  10px  10px;  }  

.example  {  text-­‐shadow:  10px  10px  red,  20px  20px  lime;  }

A burger challenge

(Disclaimer: This idea is ripped off from a great A List Apart article by

J. David Eisenberg.) http://alistapart.com/article/readspec

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

specific order?

Anyone want to volunteer? The first person to get the correct

answer during the break will win a copy of “Offscreen” magazine.

http://www.offscreenmag.com/

/*  ingredients  */  

In  the  correct  order  from  bottom  to  the  top  of  the  bun,  the  ingredients  are:  

-­‐ bottom  bun  -­‐ one  of  the  following:  mustard  or  mayonnaise  -­‐  lettuce  (optional)  -­‐  tomato  (optional)  -­‐  one  of  the  following  meats:  chicken  or  beef  -­‐  one  to  three  slices  of  the  following  cheese:  swiss  or  cheddar  -­‐ one  of  the  following  sauces:  tomato  or  bbq  -­‐ top  bun

/*  burger  syntax  */  

<burger>  =

The answer is on the following screen.

/*  burger  syntax  */  

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

Russ Weakley Max Design

Site: maxdesign.com.au Twitter: twitter.com/russmaxdesign Slideshare: slideshare.net/maxdesign Linkedin: linkedin.com/in/russweakley