How does firefox decide which #-moz-document rules to use? - css

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 */

Related

Multiple # rule functions concatenated with a comma

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.

Mozilla Firefox userChrome.css?

While researching how to create a userChrome.css for Mozilla Firefox, I found out that you can do it in different ways:
Example 1:
#namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
#-moz-document url(chrome://browser/content/browser.xul) {
#PanelUI-button {
display: none !important;
}
}
Example 2:
#namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
#PanelUI-button {
display: none !important;
}
First example contains the line #-moz-document url(chrome://browser/content/browser.xul) and the second does not. I'm not sure what it does and ouput of both examples is exactly the same.
Are there any benefits by including #-moz-document url(chrome://browser/content/browser.xul) in userChrome.css?
#-moz-document is the prefixed form of #document, a CSS "#-rule" which restricts the contained rules to certain URLs. So in this case,
#-moz-document url(chrome://browser/content/browser.xul)
restricts its contained rules to browser.xul.
Without going too deeply into userchrome.css research, I expect this means the rules will only apply to "bits of Firefox", and not actual web pages.
You could probably test it out by creating a page with an element of ID #PanelUI-button, and see if the display:none applies to it.
The #-moz-document scope restricts the style rules to that one chrome document. In this case it's the main browser UI which is what you want most of the time. Without that scope the rules would be applied to all chrome pages. This might be what you want if you're creating a theme and want consistent colors and fonts.
If your style rules are manipulating a specific element as in your example then you should limit it to the specific document, but leaving that out generally doesn't cause any problems. In this case, though, you might end up with missing buttons on some unrelated dialog if that document happened to use the same element name.
I'm answering a very old question and more recent versions of Firefox have renamed all the .xul files to .xhtml. You'd want to use #-moz-document url(chrome://browser/content/browser.xhtml) { ... } instead.
To confirm Jeremy's answer, "userChrome.css" applies only to bits of the Firefox UI, not web content. But there is a "userContent.css" file that can be used to apply custom styles to web-content. You will definitely want to scope rules in userContent.css to specific URLs or domains.

Grouping CSS #keyframes rules

I completely understand that you cannot group animation keyframes selectors such as
#keyframes,
#-moz-keyframes,
#-webkit-keyframes { /*do something*/ }
and that you absolutely MUST do
#keyframes { /*do something*/ }
#-moz-keyframes { /*do something*/ }
#-webkit-keyframes { /*do something*/ }
I know there are pre-processors that can do all this for me. But I am more interested in the reason behind why this is the case?
My google-fu is failing me. It seems to always direct me to a stackoverflow page telling someone they 'cannot' do it and they must separate them all out, or telling people about the pre-processors -or- I get sent to that horrible about.com and read stuff like
Any Selector Can be Grouped ~about.com
Which obviously is not true in this case. If someone can direct me to an article, or explain to me why it cannot be grouped it would be most helpful.
Keep in mind that at-rules and selectors are completely different things.
At-rules are covered in this section of CSS2.1 spec, which says that an at-rule consists of exactly one at-keyword followed by some statement (be it a semicolon-terminated statement, or a block). As far as the CSS parser is concerned, what you have is a set of three separate at-rules, one prefix for each vendor and one unprefixed rule for the standard.
The more appropriate counterpart to at-rules would be rule sets, or style rules, described here. A rule set consists of a selector and a declaration block (containing style declarations). This is analogous to the contents of an at-rule as described above. It also means that the selector is just one part of a rule set.
Certain at-rules do allow comma-separated values in their preludes, such as #media:
#media screen, projection {
/* Styles for both screen and projection media */
}
But instead of grouping the at-rules in entirety, the grouping happens within the value that comes after the at-keyword in the beginning of the rule.
This #media rule can be expanded into two separate rules like so:
#media screen {
/* Styles for screen media */
}
#media projection {
/* Styles for projection media */
}
Notice that each rule has its own #media at-keyword.
Similarly, when you group multiple selectors into a single rule, what you have is one style rule. The part that is grouped is the selector; everything in the declaration block that follows applies to all the selectors that are listed in the group:
.foo, .bar {
/* Styles that apply to both .foo and .bar elements */
}
And when you expand it, it becomes two rule sets:
.foo {
/* Styles that apply to .foo elements */
}
.bar {
/* Styles that apply to .bar elements */
}
Because of
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.
found at http://www.w3.org/TR/CSS21/syndata.html#rule-sets
So each vendor prefix makes the whole rule un-parseable for all the other vendors.

Override CSS media queries

I work with a page every day that uses CSS media queries I don't like; I'd rather use the full page (most of them are related to the Twitter Bootstrap menu collapsing when narrower than 768px).
Is there a way to override Bootstrap's media queries with CSS? Preferably without defining my own media queries to override all of the rules individually, as I feel like this would take a pretty long time.
Edit: I don't have control of the source code, otherwise I'd just kill the bootstrap-responsive code.
Why wouldn't you remove them in the first place?
If you can't, you still can override a CSS declaration with rules:
that have the same selector priority and come after the MQ block
that have higher selector priority than the rule in the MQ block
that have !important between the value and the semi-colon
/* one id, one class AND one element => higher priority */
#id element.class { property: value2; }
/* !important will nuke priorities. Same side effects as a nuke,
don't do that at home except if you've tried other methods */
#id .class { property: value2 !important; }
#media(blah) {
/* Overridden. Thrice. */
#id .class { property: value1; }
}
/* same selector, same everything except it comes after the one in #media?
Then the latter is applied.
Being in a #media doesn't give any more priority (but it won't be applied
everywhere, depending on "blah", that's the point of MQ) */
#id .class { property: value2; }
In the previous example, any of the declaration outside the #media block will override the one inside, e.g. there are 3 reasons why value2 will be applied and not value1.
Would like to override bootstraps responsive.css too.
I have half of the website where I want to use the default responsive.css while for another half one media query causes wrong layouts so I want to remove it.
According to my research css does not allow to remove a media query.
So I will go and copy responsive.css and remove the media query. If you have no access to the source, overrides might be the only choice.

Is there any way to get IE8 to not ignore a CSS rule that it only partially understands?

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.

Resources