Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to interpret the "Formal syntax" of CSS found on MDN

Tags:

css

I came across a CSS background property which has the following value:

background: none repeat scroll 0% 0% #F8F8F8;

The syntax of the background property is given at this MDN page, like this:

Formal syntax: [ <bg-layer> , ]* <final-bg-layer>
               where <bg-layer> = <bg-image> || <position> [ / <bg-size> ]? || <repeat-style> || <attachment> || <box> || <box>
               and <final-bg-layer> = <bg-image> || <position> [ / <bg-size> ]? || <repeat-style> || <attachment> || <box> || <box> || <background-color>

Does the order of the values of the background property matter? And, more generally: how to interpret this "Formal syntax" provided on the MDN.

like image 792
Talespin_Kit Avatar asked Nov 26 '14 15:11

Talespin_Kit


2 Answers

The formal syntax is documented at the MDN site itself. The "more general" question you have is probably too broad for Stack Overflow: just go through the documentation and come back if you have any specific questions.

One such specific question you have is whether the order of the values for the background property matters. Most parts of the background (of specifically a bg-layer) are separated by "double bars", which require no specific order according to the MDN('s formal syntax). To quote the specific documentation on double bars:

Double bar

Separating two or more components by a double bar, ||, means that all entities are options: at least one of them must be present, and they may appear in any order. Typically this is used to define the different values of a shorthand property.

As a footnote, though I love and use MDN all the time, a probably more authorative source would be W3.org, where you can find for example the background shorthand syntax as well as an explanation of the syntax in CSS Values and Units Module Level 3. It basically says the same, e.g. about "double bars":

A double bar (||) separates two or more options: one or more of them must occur, in any order.

This works in practice for the background property, as you can see in this snippet where regardless of order the properties are parsed the same:

#a { background: 100% / 2% url('http://i.stack.imgur.com/RvUr4.png') red repeat-x; }
#b { background: red repeat-x url('http://i.stack.imgur.com/RvUr4.png') 100% / 2%; }
<div id="a">A</div>
<br />
<div id="b">B</div>
like image 62
Jeroen Avatar answered Sep 27 '22 19:09

Jeroen


Order does not matter. But, order does matter.

tl;dr;

Order doesn't matter, it's what it is, in that documentation on MDN and is also corroborated by the W3C Specs. I will repeat that part verbatim:

A double bar (||) separates two or more options: one or more of them must occur, in any order.

But don't jump to that conclusion yet!

Order does matter. Let's take your example of background shorthand syntax:

[ <bg-layer> , ]* <final-bg-layer>
where <bg-layer> = <bg-image> || <position> [ / <bg-size> ]? || <repeat-style> || <attachment> || <box> || <box>
and <final-bg-layer> = <bg-image> || <position> [ / <bg-size> ]? || <repeat-style> || <attachment> || <box> || <box> || <background-color>

And, because it lists syntax of all possible properties for multiple backgrounds, let's reduce the complexity by picking one background. It looks like this:

<bg-image> || <position> [ / <bg-size> ]? || <repeat-style> || <attachment> || <box> || <box> || <background-color>

Working this out in a code snippet and relating with the documentation referred in your question and the other answer, you might believe that all these properties which are separated by a double-bar (||) can be omitted and can occur in any order. Right?

Wrong.

While MDN is a good reference, it isn't complete and can omit important details sometimes. In this particular case, both these references...

  1. MDN ref here: https://developer.mozilla.org/en-US/docs/Web/CSS/background
  2. W3C ref here: http://www.w3.org/TR/css3-background/#the-background

...state the same syntax and explain all properties, but leave out one detail.

Now look closely at the property called box. There are two box properties separated by double-bar (||). That should mean that you can either omit box or specify box in any order. But, that is not entirely correct. While you may of course omit box altogether from the shorthand, you cannot put them in any order you wish without getting unintended results. This is not stated in the MDN reference on background linked above.

But, in another reference on background-clip by same MDN here:

  1. MDN ref: https://developer.mozilla.org/en-US/docs/Web/CSS/background-clip

It states:

Canonical order: the unique non-ambiguous order defined by the formal grammar

Which means, the order is governed by ambiguity of the properties. If the properties are non-ambiguous, then the order or omission doesn't matter. If the properties are ambiguous, then the order and/or omission does matter.

In your background shorthand example, the two box properties (when present) are interpreted as the first one being background-origin and the second one being background-clip.

If you read another source of documentation here:

  1. Opera dev ref: https://dev.opera.com/articles/css3-borders-backgrounds-boxes/

It states:

There are a few things to be aware of when using the new background shorthand. If only one box value is specified both background-clip and background-origin are set to this value. If two are specified then the first is used for the origin and the second is used for the clip.

  1. And W3c ref here: http://www.w3.org/TR/css3-background/#the-background-origin

States this:

Note that if ‘background-clip’ is ‘padding-box’, ‘background-origin’ is ‘border-box’, ‘background-position’ is ‘top left’ (the initial value), and the element has a non-zero border, then the top and left of the background image will be clipped.

So, if you omit one of the values, it will be interpreted as both background-origin and background-clip. But, if you provide both the values then the order is important, otherwise you will get weird results. Not only this, the behaviour is influenced by another property of background-position.

This can be easily demonstrated using this example in the snippet below. In the first div the background-image is positioned 15px from the padding but continues across the border. Notice that the first box value is padding-box and the second one is border-box. In the second div the background-image is position 15px from the border but stops where the padding ends. Notice here that the first value is border-box and second value is padding-box. In the third div, the background-image starts from the border and continues across the border. In this case one value is omitted and both background-origin and background-clip get the value of border-box.

Snippet:

div { width: 120px; height: 120px; display: inline-block; }
#r {
    border: 15px #f00;
    border-style: dotted dashed dashed dotted;
    background: url(http://placehold.it/150) no-repeat 15px 15px padding-box border-box;
}
#g {
    border: 15px #0f0;
    border-style: dotted dashed dashed dotted;
    background: url(http://placehold.it/150) no-repeat 15px 15px border-box padding-box;
}
#b {
    border: 15px #00f;
    border-style: dotted dashed dashed dotted;
    background: url(http://placehold.it/150) no-repeat 15px 15px border-box ;
}
<div id="r">Red</div>
<div id="g">Green</div>
<div id="b">Blue</div>

Bottomline:

It is good to refer to the documentation. But, it is even better to consult multiple sources. This answer refers to 5 sources. Read the W3C specs, but not just at one place, read all related property references to see how one property can be affected by other property values, and even order. And do not forget to try out a sample, you might never know a surprise could be waiting for you!

.

like image 28
Abhitalks Avatar answered Sep 27 '22 18:09

Abhitalks