Compare Revisions

Writing efficient CSS

Change Revisions

Revision 10705:

Revision 10705 by Dria on

Revision 10706:

Revision 10706 by Dria on

Title:
Writing efficient CSS
Writing efficient CSS
Slug:
CSS/Writing_Efficient_CSS
CSS/Writing_Efficient_CSS
Tags:
css, XUL, "Best practices"
css, XUL, "Best practices"
Content:

Revision 10705
Revision 10706
tt73    <h3 name="How_the_Style_System_Matches_Rules">
74      How the Style System Matches Rules
75    </h3>
76    <p>
77      The style system matches a rule by starting with the rightm
 >ost selector and moving to the left through the rule's selectors.
 > As long as your little subtree continues to check out, the style
 > system will continue moving to the left until it either matches 
 >the rule or bails out because of a mismatch.
78    </p>
79    <p>
80      Your first line of defense is the rule filtering that occur
 >s based on the type of the key selector. The purpose of this cate
 >gorization is to filter out rules so that you don't even have to 
 >waste time trying to match them. This is the key to dramatically 
 >increasing performance. The fewer rules that you even have to che
 >ck for a given element, the faster style resolution will be. As a
 >n example, if your element has an ID, then only ID rules that mat
 >ch your element's ID will be checked. Only class rules for a clas
 >s found on your element will be checked. Only tag rules that matc
 >h your tag will be checked. Universal rules will always be checke
 >d.
81    </p>
82    <h3 name="Guidelines_for_Efficient_CSS">
83      Guidelines for Efficient CSS
84    </h3>
85    <h4 name="Avoid_Universal_Rules.21">
86      Avoid Universal Rules!
87    </h4>
88    <p>
89      Make sure a rule doesn't end up in the universal category!
90    </p>
91    <h4 name="Don.27t_qualify_ID-categorized_rules_with_tag_names
 >_or_classes">
92      Don't qualify ID-categorized rules with tag names or classe
 >s
93    </h4>
94    <p>
95      If you have a style rule that has an ID selector as its key
 > selector, don't bother also adding the tag name to the rule. IDs
 > are unique, so you're slowing down the matching for no real reas
 >on.
96    </p>
97    <ul>
98      <li>BAD - <code>button#backButton { }</code>
99      </li>
100      <li>BAD - <code>.menu-left#newMenuIcon { }</code>
101      </li>
102      <li>GOOD - <code>#backButton { }</code>
103      </li>
104      <li>GOOD - <code>newMenuIcon { }</code>
105      </li>
106    </ul>
107    <h4 name="Don.27t_qualify_class-categorized_rules_with_tag_na
 >mes">
108      Don't qualify class-categorized rules with tag names
109    </h4>
110    <p>
111      Similar to the rule above, all of our classes will be uniqu
 >e. The convention you should use is to include the tag name in th
 >e class name.
112    </p>
113    <ul>
114      <li>BAD - <code>treecell.indented { }</code>
115      </li>
116      <li>GOOD - <code>.treecell-indented { }</code>
117      </li>
118    </ul>
119    <h4 name="Try_to_put_rules_into_the_most_specific_category_yo
 >u_can.21">
120      Try to put rules into the most specific category you can!
121    </h4>
122    <p>
123      The single biggest cause of slowdown in our system is that 
 >we have too many rules in the tag category. By adding classes to 
 >our elements, we can further subdivide these rules into class cat
 >egories, and then we no longer waste time trying to match as many
 > rules for a given tag.
124    </p>
125    <ul>
126      <li>BAD - <code>treeitem{{mediawiki.external('mailfolder=\"
 >true\"')}} &gt; treerow &gt; treecell { }</code>
127      </li>
128      <li>GOOD - <code>.treecell-mailfolder { }</code>
129      </li>
130    </ul>
131    <h4 name="Avoid_the_descendant_selector.21">
132      Avoid the descendant selector!
133    </h4>
134    <p>
135      The descendant selector is the most expensive selector in C
 >SS. It is dreadfully expensive, especially if a rule using the se
 >lector is in the tag or universal category. Frequently what is re
 >ally desired is the child selector. The use of the descendant sel
 >ector is banned in UI CSS without the explicit approval of your s
 >kin's module owner.
136    </p>
137    <ul>
138      <li>BAD - <code>treehead treerow treecell { }</code>
139      </li>
140      <li>BETTER, BUT STILL BAD (see next guideline) - <code>tree
 >head &gt; treerow &gt; treecell { }</code>
141      </li>
142    </ul>
143    <h4 name="Tag-categorized_rules_should_never_contain_a_child_
 >selector.21">
144      Tag-categorized rules should never contain a child selector
 >!
145    </h4>
146    <p>
147      Avoid using the child selector with tag-categorized rules. 
 >You will dramatically increase the matching time (especially if t
 >he rule is likely to be matched more often than not) for all occu
 >rrences of that element.
148    </p>
149    <ul>
150      <li>BAD - <code>treehead &gt; treerow &gt; treecell { }</co
 >de>
151      </li>
152      <li>BEST - <code>.treecell-header { }</code>
153      </li>
154    </ul>
155    <h4 name="Question_all_usages_of_the_child_selector.21">
156      Question all usages of the child selector!
157    </h4>
158    <p>
159      Be careful about using the child selector. If you can come 
 >up with a way to avoid having to use it, do so. In particular, th
 >e child selector is frequently used with RDF trees and menus like
 > so.
160    </p>
161    <ul>
162      <li>BAD - <code>treeitem{{mediawiki.external('IsImapServer=
 >\"true\"')}} &gt; treerow &gt; .tree-folderpane-icon { }</code>
163      </li>
164    </ul>
165    <p>
166      Remember that attributes from RDF can be duplicated in a te
 >mplate! Take advantage of this fact to duplicate RDF properties o
 >n child XUL elements that wish to change based off that attribute
 >.
167    </p>
168    <ul>
169      <li>GOOD - <code>.tree-folderpane-icon{{mediawiki.external(
 >'IsImapServer=\"true\"')}} { }</code>
170      </li>
171    </ul>
172    <h4 name="Rely_on_inheritance.21">
173      Rely on inheritance!
174    </h4>
175    <p>
176      Learn which properties inherit, and allow them to do so! We
 > have explicitly set up XUL widgetry so that you can put list-sty
 >le-image (just one example) or font rules on the parent tag, and 
 >it will filter in to the anonymous content. You don't have to was
 >te time writing a rule that talks directly to the anonymous conte
 >nt.
177    </p>
178    <ul>
179      <li>BAD - <code>#bookmarkMenuItem &gt; .menu-left { list-st
 >yle-image: url(blah); }</code>
180      </li>
181      <li>GOOD - <code>#bookmarkMenuItem { list-style-image: url(
 >blah); }</code>
182      </li>
183    </ul>
184    <p>
185      In the above example, the desire to style the anonymous con
 >tent (without understanding that list-style-image inherits) resul
 >ted in a rule that was in the class category, when this rule real
 >ly should have ended up being in the most specific category of al
 >l, the ID category.
186    </p>
187    <p>
188      Remember, especially with anonymous content, that they all 
 >have the same classes! The bad rule above causes the icon of ever
 >y menu to be checked to see if it is contained in the bookmarks m
 >enu item. This is hideously expensive (since there are many menus
 >); this rule never should have even been checked by any menu othe
 >r than the bookmarks menu.
189    </p>

Back to History