When a CSS Property Can Have Multiple Values, Are Those Values Always Separated by Whitespaces

When a CSS property can have multiple values, are those values always separated by whitespaces?

The technical answer to your question is that it depends entirely on the property itself.

But generally, yes, whitespace is used to separate different components of a property value in CSS.

As you've seen in the font-family property however, the value that it takes is a comma-separated list of fonts (commonly called a font stack). The fact that it uses a comma as a delimiter is defined solely by the specification for that property, see CSS2.1, section 15.3:

The property value is a prioritized list of font family names and/or generic family names. Unlike most other CSS properties, component values are separated by a comma to indicate that they are alternatives:

body { font-family: Gill, Helvetica, sans-serif }

And CSS Fonts level 3, section 3.1:

Unlike other CSS properties, component values are a comma-separated list indicating alternatives.

Whitespace is acceptable either in front of the comma or behind it, or both. It is not significant and will not alter the meaning of the property value. The convention that is shown in the W3C specs is a single space after the comma. The page you link to is W3Schools which may have its own conventions (which in fact it apparently does not — even its own examples aren't consistent in the use of whitespace).

Indeed, even the font property, despite being a shorthand, has a custom syntax: in order to specify line-height, font-size has to be specified followed by a forward slash, which means, for example, font: 12px/1.5 is equivalent to font-size: 12px; line-height: 1.5. See this answer.

But again, there is no definite all-encompassing answer to what character is used as a delimiter in a property value. Each CSS property has its own grammar of possible values which is always spelled out in its respective specification.

Difference between space and comma -- CSS property values(not in selector)

Space:

Each value make different function. For example:

font: bold 60px helvetica, arial, sans-serif; 

bold = font-weight: bold;

60px = font-size: 60px;

bold do the weight and 60px do the size, these two are different from each other.

Comma:

helvetica, arial, sans-serif = font-family: helvetica, arial, sans-serif;

Values in comma do the same function. They all change font-family.
In this case:

If helvetica it's not supported then loads arial, if arial it's not supported then loads sans-serif.

Using fonts with two words:

If you use fonts that contains two words and have spaces like Roboto Slab.

For these fonts you have to put them on double quotes "roboto slab".

Example: font: bold 60px "roboto slab", arial, sans-serif;

Why is there no comma when adding multiple transforms in css

This is actually a very good observation. Shame on these people saying it is just because. The spec isn't some magical tablet like the 10 commandments, that just appears into existence. It is extensively debated by several members of the community (mediated by W3), until there is some sort of consensus. Then the developers (mostly browser developers I imagine) will take the specs and implement. The interesting part is that the debate is open and public. So not only you can participate by giving your opinion on upcoming specs, but you can also search back and find out all the arguments that led to a consensus: https://lists.w3.org/Archives/Public/www-style/2004Oct/

I haven't read the whole discussion, but I can imagine that an implementation without commas would be harder and less predictable, since each background holds a set of properties. So for example, on the background shorthand it would be impossible to say where one background declaration starts and the other one ends, since there are no required properties. Like background: red url(img.png);. Is that one bg or two? And this is definitely two: background: red, url(img.png);

That is just what pops up in my head, but if you dig into the discussion you will see that there are all sorts of considerations, like the effect on other APIs, like js, backwards compatibility, etc

What are the rules around whitespace in attribute selectors?

The rules on whitespace in attribute selectors are stated in the grammar. Here's the Selectors 3 production for attribute selectors (some tokens substituted with their string equivalents for illustration; S* represents 0 or more whitespace characters):

attrib
: '[' S* [ namespace_prefix ]? IDENT S*
[ [ '^=' |
'$=' |
'*=' |
'=' |
'~=' |
'|=' ] S* [ IDENT | STRING ] S*
]? ']'
;

Of course, the grammar isn't terribly useful to someone looking to understand how to write attribute selectors, as it's intended for someone who's implementing a selector engine.

Here's a plain-English explanation:

Whitespace before the attribute selector

This isn't covered in the above production, but the first obvious rule is that if you're attaching an attribute selector to another simple selector or a pseudo-element, don't use a space:

a[href]::after

If you do, the space is treated as a descendant combinator instead, with the universal selector implied on the attribute selector and anything that may follow it. In other words, these selectors are equivalent to each other, but different from the above:

a [href] ::after
a *[href] *::after

Whitespace inside the attribute selector

Whether you have any whitespace within the brackets and around the comparison operator doesn't matter; I find that browsers seem to treat them as if they weren't there (but I haven't tested extensively). These are all valid according to the grammar and, as far as I've seen, work in all modern browsers:

a[href]
a[ href ]
a[ href="http://stackoverflow.com" ]
a[href ^= "http://"]
a[ href ^= "http://" ]

Whitespace is not allowed between the ^ (or other symbol) and = as these are treated as a single token, and tokens cannot be broken apart.

If IE7 and IE8 implement the grammar correctly, they should be able to handle them all as well.

If a namespace prefix is used, whitespace is not allowed between the prefix and the attribute name.

These are incorrect:

unit[sh| quantity]
unit[ sh| quantity="200" ]
unit[sh| quantity = "200"]

These are correct:

unit[sh|quantity]
unit[ sh|quantity="200" ]
unit[sh|quantity = "200"]

Whitespace within the attribute value

But notice the quotes around the attribute values above; if you leave them out, and you try to select something whose attribute has spaces in its value you have a syntax error.

This is incorrect:

div[class=one two]

This is correct:

div[class="one two"]

This is because an unquoted attribute value is treated as an identifier, which doesn't include whitespace (for obvious reasons), whereas a quoted value is treated as a string. See this spec for more details.

To prevent such errors, I strongly recommend always quoting attribute values, whether in HTML, XHTML (required), XML (required), CSS or jQuery (once required).

Whitespace after the attribute value

As of Selectors 4 (following the original publication of this answer), attribute selectors can accept flags in the form of an identifier appearing after the attribute value. Two flags have been defined pertaining to character case, one for case-insensitive matching:

div[data-foo="bar" i]

And one for case-sensitive matching (whose addition I had a part in, albeit by proxy of the WHATWG):

ol[type="A" s]
ol[type="a" s]

The grammar has been updated thus:

attrib
: '[' S* attrib_name ']'
| '[' S* attrib_name attrib_match [ IDENT | STRING ] S* attrib_flags? ']'
;

attrib_name
: wqname_prefix? IDENT S*

attrib_match
: [ '=' |
PREFIX-MATCH |
SUFFIX-MATCH |
SUBSTRING-MATCH |
INCLUDE-MATCH |
DASH-MATCH
] S*

attrib_flags
: IDENT S*

In plain English: if the attribute value is not quoted (i.e. it is an identifier), whitespace between it and attrib_flags is required; otherwise, if the attribute value is quoted then whitespace is optional, but strongly recommended for the sake of readability. Whitespace between attrib_flags and the closing bracket is optional as always.

How to prevent division when using variables separated by a slash in CSS property values

Use the #{} interpolation notation to treat your variables as strings. Since Sass cannot perform arithmetic on strings, the / gets treated as a literal slash instead of the division operator:

@mixin test($fontsize, $lineheight) {
font: #{$fontsize}/#{$lineheight} sans-serif;
}

Why is my attribute selector working when it doesn't have any whitespace in it?

It's not separated by whitespace but:

a whitespace-separated list of words

Which mean a list of words where you have whitespace between and if alone no need whitespace because there is nothing to separate.

[data-vegetable~="liquid"] {  color: red;}
<ul>  <li data-vegetable="liquid other and other">this one</li>  <li data-vegetable="liquid">and this one</li>  <li data-vegetable="liquid   ">also this one</li>    <li data-vegetable="another liquid   ">also this one</li>  <li data-vegetable="liquid-one">NOT this one !!</li>  <li data-vegetable="another-liquid">NOT this one !!</li>  <li data-vegetable="aliquid">NOT this one !!</li></ul>

What does the forward slash mean in the CSS font shorthand?

12px is the font size, 18px is the line height.

The syntax is based on typographical notation for specifying the respective sizes, and is only applicable to the font shorthand property. In other words, the above declaration simply expands to the following:

font-size: 12px;
line-height: 18px;

As always, if you set the line height to a relative value (e.g. percentage or ems), it's calculated relative to the font size.

W3C CSS2.1 font property reference

W3C CSS3 Fonts Module font property reference (the syntax carries over from CSS2.1)

Targeting a class value that begins with a space

Any leading or trailing spaces in the value of a class attribute are meaningless for targeting purposes. This: class=" example" is equivalent to this: class="example".

There is no need for a special selector that factors in the space.

From the HTML 5 spec:

2.4.7 Space-separated
tokens

A string containing a set of space-separated tokens may have leading
or trailing space characters.

Space characters are necessary, however, for separating multiple values in a class attribute.

3.2.5.7 The class
attribute

The attribute, if specified, must have a value that is a set of
space-separated tokens representing the various classes that the
element belongs to.

Is it possible to use the space character in CSS class names?

https://html.spec.whatwg.org/multipage/dom.html#classes

When specified on HTML elements, the class attribute must have a value that is a set of space-separated tokens representing the various classes that the element belongs to.

Of course it’s possible to escape a space character, e.g. — HTML attribute values can contain character references per https://html.spec.whatwg.org/multipage/syntax.html#syntax-attribute-value:

Attribute values are a mixture of text and character references, except with the additional restriction that the text cannot contain an ambiguous ampersand.

However, it doesn’t matter whether the space is HTML-escaped or not for the above statement to apply. A HTML-encoded space character still decodes to a space character, and so e.g. class="a b" still results in “a set of space-separated tokens”. See e.g. https://html.spec.whatwg.org/multipage/parsing.html#attribute-value-(double-quoted)-state for how double-quoted attribute values are parsed.

Is there a CSS shorthand to write a rule that overrides a property for multiple classes if they are descendants of a specific class?

Maybe you should consider using some of dynamic stylesheet language like LESS. It allows you to make nested classes. Example:

.top {
.normal {
font-weight: 400;
}
.other {
font-weight: 700;
}

}

Will compile to:

.top .normal {font-weight: 400;} .top .other {font-weight: 700;}


Related Topics



Leave a reply



Submit