I'm trying to have some custom rules for firefox, and up until now I used
#-moz-document url-prefix()
But according to the docs #-moz-documentwill not be supported in future versions.
Instead #document will be supported.
So I changed from this:
#-moz-document url-prefix() {
...
}
To this
#-moz-document url-prefix(),
#document url-prefix() {
...
}
But for some reason now, the rules no longer apply
The reason this won't work is that chained CSS selectors/directives are evaluated as one.
If one of the parts fails evaluation the entire style is disregarded
Example:
// 😔
[type="range"]::-moz-range-thumb, [type="range"]::-ms-thumb { ... }
makes IE skip makes Firefox skip
// 😀
[type="range"]::-moz-range-thumb { ... } makes IE skip (Firefox will work)
[type="range"]::-ms-thumb { ... } makes Mozilla skip (IE will work)
In your case current Firefox will understand #-moz-document url-prefix() but not #document url-prefix() causing it to skip the style.
Therefore when dealing with vendor specific implementations always keep your styles separated.
I hope it made sense :-)
From the MDN page:
From version 61: this feature is behind the
layout.css.moz-document.content.enabled preference (needs to be set to
true). To change preferences in Firefox, visit about:config.
Related
#-moz-document has been a quite useful hack to target Firefox in CSS. For instance,
#-moz-document url-prefix() {
/* Firefox-specific rules */
}
But now since https://bugzilla.mozilla.org/show_bug.cgi?id=1035091 has been fixed, the old hack does not work anymore in Firefox Developer Edition and I believe this patch will land in the stable version soon. So
As Far As I Understand, UA sheets are the ones come with the browser for default element looking but what are user sheets?
Are there any CSS-only alternative implementations?
You could use a #supports feature query testing some specific vendor prefixed -moz- value, e.g.
Codepen demo
<p class="moz">Is it Mozilla?</p>
CSS
.moz::after { content: " nope."}
#supports (display: -moz-grid) {
.moz::after { content: " yep!"}
}
Note that this method will work until that specific value (e.g. -moz-grid) is not removed from the vendor in the future and can be also used to detect other vendor values (like display: -webkit-box or display: -ms-flexbox)
I have used this hack to make css changes needed for firefox. It has worked, but when I validated the code I have the below error. Can I use the code below, or is there a better way?
751 Sorry, the at-rule #-moz-document is not implemented.
798 Parse Error }
/*********************************
FIRE FOX HACK TO FIX ERRORS
***********************************/
#-moz-document url-prefix() {
#rectangle {
width: 1030px;
right: -100px;
}
}
Any CSS at-rule that starts with #-moz- is a Gecko-engine-specific rule i.e. it is a Mozilla-specific extension, not a standard rule.
The url-prefix rule here applies the contained style rules to any page whose URL starts with it. When used with no URL argument like #-moz-document url-prefix() it applies to ALL pages. That's effectively a CSS hack used to only target Gecko (Mozilla Firefox). All other browsers will ignore the styles.
Hence, you can perfectly use #-moz- styles to target only the Firefox browser.
See here for a list of other Mozilla-specific extensions.
See here for valid #moz document rules.
I've created a custom userContent.css file for Firefox 26 running on Fedora 19.
I trying to figure out the precedence order to #-moz-document rules.
What I would like to do is to have a set of rules for the community pages and another set if rules for all other pages on the site.
I tried...
#-moz-document
url-prefix(https://discussions.apple.com/community/)
{/* rules for this page */}
#-moz-document
domain(discussions.apple.com)
{ /* different rules for all other pages in domain. */}
What I found was that my url-prefix rules were ignored.
Well if you have identical attributes in both rules, then the latter are going to overwrite the former because CSS when all thing are considered equal applies rules from top to bottom, so since https://discussions.apple.com/community/ also matches discussions.apple.com the rules from the latter will apply, if you want you can swap the order and this should help.
/*
Where to place a new css tag?
Find the conditional code, "the if statements".
The conditional code starts with #.
In some ways, you can think that all the css rules
are applied that in parallel.
In the case you add a new rule with with an attribute that you haven't used
before, the rule can be place anywhere in the conditional block that applies.
In case of conflicting attributes, the last
seen attribute is used.
*/
/* if the domain of the web page is any of these,
apply the css below, between the matching {}. */
#-moz-document
domain(discussions.apple.com),
domain(communities.apple.com),
domain(discussionsjapan.apple.com),
domain(discussionskorea.apple.com)
{
... lots of css ...
/* for pages from all devices and the width of the page
is larger than 1265px, apply the css.
Remember, we are inside of the #-moz-document conditional.
So the #media rule, only see pages that of passed #-moz-document
conditional. */
#media all and (min-width: 1265px)
{
/* styles for a large browser window */
... lots of css ...
}
/* for pages from all devices and the width of the page
is less than or equal to 1265px, apply the css. */
#media all and (max-width: 1265px)
{
/* styles for narrow browsers window */
... lots of css ...
}
} /* end of #-moz-document */
/* another conditional. The style rules will be applied
to any page with an URL starting with. Note, this
#-moz-document rules is applied separately from the
prior #-moz-document conditional. */
#-moz-document
url-prefix(https://discussions.apple.com/people/),
url-prefix(https://discussions.apple.com/welcome),
url-prefix(https://discussionsjapan.apple.com/people/),
url-prefix(https://discussionsjapan.apple.com/welcome/),
url-prefix(https://discussionskorea.apple.com/people/),
url-prefix(https://discussionskorea.apple.com/welcome/)
{
/* These rules get applied on the pages that match.
Remember, the last setting of the attribute wins. */
... lots of css ...
} /* end of #-moz-document */
Why does not the css rules work in Chrome?
css:
.selector { (;property: value;); }
or
.selector { [;property: value;]; }
First off, this isn't a hack. Equally, this doesn't only apply to Chrome v30. The same functionality applies in all other modern browsers.
As defined here in the CSS2.1 specification:
...parentheses (( )), brackets ([ ]), and braces ({ }) must always occur in matching pairs and may be nested.
When you add a (, for instance, Chrome will wait for the closing ) before attempting to apply any styles. However, no CSS property is wrapped in parenthesis like this, so thus no style is applied.
Take this example:
.selector {
(color:#f00;); /* Invalid, ignored. */
font-weight:Bold; /* Valid, not ignored. */
}
Here the color declaration is in parenthesis and the font-weight declaration isn't. Chrome will ignore the color property altogether as this is not a valid CSS declaration, but still process the font-weight as normal:
JSFiddle demo.
Parenthesis, brackets and braces like this are simply invalid CSS declarations and are ultimately ignored in the same way that the following would also achieve the same:
.selector {
color; /* Invalid, ignored. */
font-weight:Bold; /* Valid, not ignored. */
}
It's also worth noting that Chrome will treat anything between parenthesis and brackets as a single CSS declaration. In your case, (;property: value;); is treated as one declaration, regardless of the extra semicolons.
It's also worth noting that if you fail to match the closing pair prior to ending the selector (with a }), any selector given after will not be processed (example).
That particular set of CSS oddities is actually known, and what is called bracket hacks for Safari (yes they have a name). They also worked in Chrome until version 28. It works in versions 7.0 and older in Safari at this time (version 8 is the current version of Safari as I am writing this update).
I just ran into what seems like absurd behavior to me. If IE8 doesn't understand part of a rule it ignores the entire thing:
input[type=radio]:checked,
input.checked {
/* Some CSS */
}
I already have IE8 specific JS adding the .checked class, but because it doesn't understand :checked, it ignores the entire thing, so I'm forced to now have several rules:
input[type=radio]:checked{
/* Some CSS */
}
input.checked {
/* The exact same CSS */
}
So my question -- does anyone know of a way to get IE8 and below to ignore the :checked instead of throwing out the entire rule?
Very basic example: http://jsfiddle.net/8UT56/
You can use a library like http://selectivizr.com/ to give IE newer selectors.