Forum Moderators: not2easy

Message Too Old, No Replies

inheritance and css bloat

is there such a thing as an ascendant selector?

         

hairycoo

11:15 pm on Feb 23, 2006 (gmt 0)

10+ Year Member



I'm trying to reduce some code bloat and have run into some problems. Was hoping for some suggestions :)

Q1: Is there a way to rewrite this

div.content h1, div.content h2, div.content h3, div.content p {
margin: 10px 20px 10px 270px;
}

so that it's shorter but means the same? Something like all h1, h2, h3 and p within div.content should be so and so.

Q2: I have <li><a href="/" class="red">bla bla</a></li>. Is there a way to easily apply a value to the <li> by using the a.red?

Something like... the li in which a.red is contained should be color: black;... sort of ascendant selectors?

I've had a look here [w3.org...] but have trouble understanding these two things

UL OL+LI {} /* a=0 b=0 c=3 -> specificity = 3 */
H1 + *[REL=up]{} /* a=0 b=1 c=1 -> specificity = 11 */

Thanks

coopersita

12:30 am on Feb 24, 2006 (gmt 0)

10+ Year Member



Q1: The only way I can think of simplifying it is by writing:

.content h1, .content h2, .content h3, .content p {
margin: 10px 20px 10px 270px;
}

Not much change though.

Q2: As far as I know you can't target a parent through the child.

The + is a sibling selector, where you can target a selector that is next to another, but not inside another.

Google selectutorial for an excellent tutorial on selectors.

jessejump

1:15 am on Feb 24, 2006 (gmt 0)

10+ Year Member



It's not inheritance or specifity you need here, it's grouping and contextual selectors.

Consider renaming the div.content to div.c to save bloat.
Google uses one letter names for classes and ids.

bedlam

6:50 am on Feb 24, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Consider renaming the div.content to div.c to save bloat.

This is simply a silly suggestion--unless the site in question has gargantuan bandwidth costs (and even then, optimizing the HTML pages is probably a much better place to start). A stylesheet for a site I maintain runs 1300 lines including extensive comments. All of that code--and in my experience, that's an unusually long css file--takes up 22kb. That 22kb is requested by the visitor's browser exactly once per site visit.

If ".content" appeared one hundred times in my stylesheet, it would be a good sign that the stylesheet could benefit from the grouping and contextual selectors that you very properly suggested, but what would be saved by renaming the class?

Well, you'd save six bytes per occurrence. Multiply that by one hundred, and you save six hundred bytes--that's 2.3% of the total size of the file.

Weigh those puny savings against the cost to code readability; I know which I'd choose...

Google uses one letter names for classes and ids.

I wouldn't necessarily look to Google as a model. Their html [validator.w3.org] has never been such that you'd want to imitate it, their css consists of three declarations, and they must see millions upon millions of visits per day...

-b

Wlauzon

8:03 am on Feb 24, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Does the CSS page load once, or on each page?

.. always wondered about that...

SuzyUK

8:57 am on Feb 24, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Q1: Is there a way to rewrite this

div.content h1, div.content h2, div.content h3, div.content p {
margin: 10px 20px 10px 270px;
}

.content * {margin: 10px 20px 10px 270px;}

will target every element inside the content div.. which might help, and then if there are any exceptions like a ul for example

.content ul {margin: 20px;}

the second will override the first because it's more specific (note: the asterisk or universal selector is worth nothing in specific terms)

.content * = attribute (class) = 0,1,0
.content ul = attribute (class) & element (ul) = 0,1,1

please note! the above is theory only - and that it will not work well in practice as it will also target all other descendants of .content too so if you have more than 1 level of descendants, say <div.content><ul><li><a>, then <ul> <li> and <a> will all get those margins ~ so this is not really recommended unless you only have one level deep to target or your exceptions can be coded with less bloat than the originals - dropping the div is likely the best for now as coopersita says

if IE had support then the answer could be

.content > *
- the > (whitespace optional) is a child selector so would only target the direct children of .content (not granchildren or great.. greats..)

Q2: I have <li><a href="/" class="red">bla bla</a></li>. Is there a way to easily apply a value to the <li> by using the a.red?

Something like... the li in which a.red is contained should be color: black;... sort of ascendant selectors?


No ascendant selectors however you can use specificity if you place ID's and classes prudently.. e.g. if you remove the class name from the <a> in the above scenario and say place it on a <ul> (btw.. I know red isn't a good name but just carrying on the theme..)

<ul class="red">
<li><a href="......
<li class="active><a href....
</ul>

You can then target the ul, li and a elements separately using the one class name you can even target further if there were nested lists.. only reason for a class name on an <a> is if you cannot specifically target it via an ascendant class or ID, combined with parent elements, a special case IMHO..

.red {background: #cfc;}
.red li {color: black;}
.red li a {color: lime;}
.red li.active a {color: pink;}

the active link color will override the lime colored link again because of specificity

.red li a = attribute (class) & element (li) & element (a) = 0, 1, 2
.red li.active a = attribute (class) & element (li) & attribute (class) & element (a) = 0, 2, 2

UL OL+LI {} /* a=0 b=0 c=3 -> specificity = 3 */
H1 + *[REL=up]{} /* a=0 b=1 c=1 -> specificity = 11 */

ul ol+li = element (ul) & element (ol) & element (li) = 0, 0, 3
h1 + *[rel=up] = element(h1) & attribute (rel) = 0, 1, 1

----------------
ref: all of the above specificity calculations, I have numbered them in accordance with the specificity rules on that W3C page

A selector's specificity is calculated as follows:
  • count the number of ID attributes in the selector (= a)
  • count the number of other attributes and pseudo-classes in the selector (= b)
  • count the number of element names in the selector (= c)
  • ignore pseudo-elements.

but I've separated them (a, b, c) with commas this was deliberate. The way the W3C have their example is slightly misleading.. you would automatically think to look at their example that it is base ten and the number should be read 100 (one hundred) and 100 is higher than 3 ~ while normally it's OK to do that - you should read each bit for what it is with "a" trumping "b" trumping "c" first of all. Then if you get to the stage that you cannot seperate them using the IS "a" then IS "b" then IS "c" parts alone the highest pipped one in "a", then "b", then "c" wins..

for instance you might have three selectors like this..

#top .a1 .a2 .a3 .a4 .a5 .a6 .a7 .a8 .a9 .a10 .a11 .a12 p {color: blue;}
#top #next p {color: red;}
#top p {color: yellow;}

the first one is highly unlikely I know but it's possible,

the specificity calculation on the first becomes :
1, 12, 1 - 1 x ID, 12 x attribute(class), 1 x element

and the second become
2, 0, 1 - 2 x ID's, 0 x attributes, 1 x element

and the third become
1, 0, 1 - 1 x ID, 0 x attributes, 1 x element

1121 would seems like it's higher than 201 - but in actual fact the second example is more specific than the first

2, 0, 1 beats 1, 12, 1 and 1, 0, 1

they all have to be considered because they all have an "a" count and there is one "a" count higher than the other two so it wins - and "b" and "c" don't enter into this comparison

but then 1, 12, 1 is more specific than 1, 0, 1

they both have an "a" count of 1 so we need to go to the "b" count to determine the winner and 12 is higher than 0 so this one is determined on the "b" count and c doesn't matter

therfore order of ranking top first =
2, 0, 1
1, 12, 1
1, 0, 1

which would not be easy to understand if it where written the W3C way would it ;)
201
1121
101

Anyway.. that's my rant on specificity (oh gimme a break I've haven't done it for a while :)) and hope it helps

Suzy

uh oh.. just reading and would like to go back to first example to clarify something..

.content * = attribute (class) = 0,1,0
.content ul = attribute (class) & element (ul) = 0,1,1

if you did write the first selector as

div.content
instead of just
.content
& for arguments sake, this would change things very subtly..

div.content * = element (div) & attribute (class) = 0,1,1
.content ul = attribute (class) & element (ul) = 0,1,1

the selectors now have exactly the same specificity in which case the second one would still win but this time only by the order of the cascade ;) So the best bet not only for less bytes is to start off with the least amount you need and only add more if you have to.. if you start with div.content you might end up having to use it all the way through in order to keep up with further nested specifics, which of course might add to the code bloat

..

jessejump

8:41 pm on Feb 24, 2006 (gmt 0)

10+ Year Member



>>>> but what would be saved by renaming the class?

Oh, nothing would be saved as you pointed out. I was just thinking outside the .wrapper.
Does every class have to be .nav, .content, .leftcol, .wrapper, .foo, .bar, .footer? Whatever works for the author.