What's the expected behavior of an empty CSS declaration? - css

For example:
.foo { font-family: ; font-size: ; }
I'm seeing different behaviors in IE9 and Chrome. IE9 seems to use this to zero out those attributes (although, this behavior isn't being consistent across different pages for me at the moment).
In Chrome, it seems to simply ignore it.
What is the true expected behavior? Is that even valid CSS?

That is invalid CSS.
Browsers are supposed to ignore declarations without values (and only each declaration, not the entire block or everything after an invalid declaration). From the spec (irrelevant code examples omitted):
Malformed declarations. User agents must handle unexpected tokens encountered while parsing a declaration by reading until the end of the declaration, while observing the rules for matching pairs of (), [], {}, "", and '', and correctly handling escapes. For example, a malformed declaration may be missing a property, colon (:) or value. The following are all equivalent:
p { color:green }
p { color:green; color: } /* malformed declaration missing value */
p { color:red; color:; color:green } /* same with expected recovery */

Chrome is right. See: p { color:green; color: } here:
http://www.w3.org/TR/CSS2/syndata.html#parsing-errors

Related

Less Mixin using variable in attribute selector

EDIT: The issue might be with a bug in dotless, which is what we're using.
I'm trying to write a Less Mixin method for writing out a lot of CSS styles. The general format of the method is:
.icon-styles(#name) {
.#{name}-icon {
background-image: url('../images/icon-#{name}.png');
display: none;
}
[data-#{name}="true"] .#{name}-icon {
display: inline-block;
}
}
Such that the icon is only visible if a containing object has the related attribute set.
However, I'm getting an error at the attribute selector saying:
Expected ']' but found '{'
Pointing to the # inside the square brackets.
I've found this post:
LESS mix variable into attribute name in an attribute selector expression
With a similar issue, and the answer suggests it might be a bug, but unfortunately the workaround doesn't work for me. I'm getting the same error on trying to write out attr inside the brackets.
I've also tried writing it like this:
[~'data-#{name}'="true"] .#{name}-icon {
Which gets rid of the error, but then #{name} is not resolved in the resulting css.
Does anyone know if there's any way to achieve what I want?
The trick is the same as suggested in LESS mix variable into attribute name in an attribute selector expression. You're just missing the main point of it: "concatenation of interpolated variables is not supported inside [attr] blocks", so you need to move out of it:
.icon-styles(#name) {
.#{name}-icon {
background-image: url('../images/icon-#{name}.png');
display: none;
}
#data-name: ~'data-#{name}';
[#{data-name}="true"] .#{name}-icon {
display: inline-block;
}
}

LESS: mixin with non-class ruleset

In LESS, I am trying to define the button.c2 ruleset, to be applied to <button class="c2">...</button> elements. This ruleset is mainly based on the button.c1 ruleset. However, the following code produces a ParseError:
button.c2 {
button.c1;// Trying to import a ruleset
... // additional rules, such as font-size: 120%;
}
It seems to me that the ParseError is caused by the fact that the imported ruleset does not refer to a class or ID ("button.c1" does not start with a "." or a "#"). From the LESS documentation:
Any CSS class or id ruleset can be mixed-in that way.
Why is there such a limitation? Is there any way around it?
The limitation might just be ease of parsing, since . or # don't show up as the first character of a normal style rule the parser automatically knows that those should be mixed in.
You could get around it by defining .c1 as a mixin and using it for both buttons:
.c1() {
// c1 rules
}
button.c1 {
.c1;
}
button.c2 {
.c1;
// additional rules
}
However, coming up in LESS 1.4.0 are :extend selectors, which will allow you to do what you want. The syntax would be:
button.c2:extend(button.c1) {
// additional rules
}

Why can't vendor prefixed selectors be placed on the same line?

I recently realized, when styling HTML5 input placeholder text, that this does not work:
:-moz-placeholder, ::-webkit-input-placeholder {
color:rgb(150,150,150);
}
But this does:
:-moz-placeholder {
color:rgb(150,150,150);
}
::-webkit-input-placeholder {
color:rgb(150,150,150);
}
Does anyone know why this is the case?
One of the :-vendor-... selector is not recognised, thus invalid. Rules containing invalid pseudo-selectors are ignored.
Have a look at this fiddle: http://jsfiddle.net/ue44U/2/
The #foo selector should match the element at the example, but since I've added :a-cow-says-moo to the selector set, the whole rule is ignored.

How to combine this css?

.box_content ::selection {
background:#CCCC33; /* Safari */
}
.box_content ::-moz-selection {
background:#CCCC33; /* Firefox */
}
Anyone know if I can combine those like this?
.box_content ::selection .box_content ::-moz-selection {
background:#CCCC33;
}
Or maybe like:
.box_content ::selection, .box_content ::-moz-selection {
background:#CCCC33;
}
The second one is correct. You can use a comma to separate css selection rules.
So given:
selector-rule1, selector-rule2 {
style-x;
style-y;
}
This will apply style-x & style-y to anything that matches either selector-rule1 or selector-rule2.
Just to explain why your first example won't work, its because spaces imply ancestor-descendant relationships, so if you have:
selector-rule4 selector-rule4 {
style-z;
}
Then style-z will be applied to anything that matches selector-rule4 if it is also an an ancestor of something that matches selector-rule3.
More info on selectors here.
Your second example should work fine.
You need to use a comma to group the selectors:
.box_content ::selection, .box_content ::-moz-selection {
background:#CCCC33;
}
Your second example can’t work because a browser has to ignore the complete rule:
When a user agent cannot parse the
selector (i.e., it is not valid CSS
2.1), it must ignore the selector and the following declaration block (if
any) as well.
Opera and Webkit can’t parse the Gecko proprietary selector and Gecko can’t parse the regular ::selection. So the rule will never be applied.

Doing quotes in CSS

I have some legacy CSS I wanted to clean up. Person who wrote it is not available for consultation. The following rule does not validate (CSS 2.1):
html[lang=en] q: before, : lang(en) q: before {
content: "“";
}
Would it be safe to assume that the author mean the following (this validates):
html[lang=en] q:before, q:lang(en):before {
content: "“";
}
Also, is the first selector different from the second one in any way? Is each specific to a certain browser?
Thanks.
This selector does not appear to work in Firefox:
: lang(en) q: before
It is probably supposed to be
:lang(en) q:before
Which is not the same as
q:lang(en):before
You can see this in action with the following test case:
:lang(en) q:before {
content: "a";
}
q:lang(en):before {
content: "b";
}
<div lang="en">
<q lang="zh">Hello zh</q> <q lang="en">Hello EN</q> <q>Hello Plain</q>
</div>
This gives
a"Hello zh" b"Hello EN" b"Hello Plain"
Basically the :lang(en) q:before rule says "Before any Q inside any element with English language", while q:lang(en):before says "before any Q that is in the English Language".
Also, the two selectors that are used (html[lang=en] q:before and :lang(en) q:before) are not exactly equivalent but will achieve the same effect most of the time if the browser in question understands one of the selectors. :lang(en) is a newer selector that identifies the language while html[lang=en] is an attribute selector that merely identifes some attribute called lang.
this is definately wrong :
before, : lang(en)
the , : can't be used like this, the comma indicates a new "rule", the colon a pseudp property (like in a:link).
P.S. do content and before work in IE?

Resources