views:

57

answers:

4

I'd like two different HTML elements that are at the same nesting level to have identical CSS property values. Is there an alternative to this wasteful syntax?

.level1 .level2 .level3 element1 { /*rules*/ }
.level1 .level2 .level3 element2 { /*rules*/ }

I was thinking

.level1 .level2 .level3 element1, .level1 .level2 .level3 element2 { /*rules*/ }

...but this looks confusing and doesn't reduce much.

Is the best method to define a new class?

+5  A: 
.level1 .level2 .level3 element1, 
.level1 .level2 .level3 element2 { }

or

.level1 .level2 .level3 * { }

are your only other syntactical alternatives if you don't alter the source code. The latter would fail if you have other elements other than element1 and element2. I'd go with the former.

meder
the * looks good, but is there syntax to replace it with a specific set of elements to affect?
smchacko
it will target every element at that specific level, which is why I'd use the former. CSS isn't a programming language or anything, it's most widely supported selectors are very primitive which is why you can't do anything fancy.
meder
+1  A: 

Well if you're putting classes on them like "level2" then just do:

.level2 { /* rules */ }

meaning there's no need to go:

.level1 .level2 .level3 { /* rules */ }

if you simply assume that level3 is correctly placed, which should simplify such things as:

.level3 div, .level3 span, .level3 p { /* rules */ }

versus the alternative.

There is no way of saying:

.level3 (div or span or p) { /* rules */ }

unfortunately.

but if you want to specify the rules by element depth, it's a little trickier. The easiest way is to use the child selector:

ul li > ul li > ul li { /* rules */ }

if you know the structure and can reasonably express it. The problem with this approach is that IE6 doesn't support the child selector. If you do this:

ul li ul li ul li { /* rules */ }

those rules will apply to the 3rd level and below, not just the third level. That can get tricky to correctly specify in light of rules at different levels that might contradict each other:

ul li { /* rules for 1st, 2nd, 3rd level */ }
ul li ul li { /* rules for 2nd and 3rd level */ }
etc

That might work depending on what you want to do or it might not.

cletus
yeah, my example isn't the best, but my goal was to reduce the amount of CSS written, I thought there might be something like .someclass1 .someclass2 [a,p,div] {/*rules*/}, where I could specify all the affected elements at once, instead of .someclass1 .someclass2 a {/*rules*/} .someclass1 .someclass2 p {/*rules*/} .someclass1 .someclass2 div {/*rules*/}
smchacko
Yeah, there isn't.
cletus
whoops, I skipped over the part where you wrote:There's no way of saying:.level3 (div or span or p) { /* rules */ }thanks
smchacko
A: 

If

.level1 .level2 .level3 element1, .level1 .level2 .level3 element2 { /*rules*/ }

looks confusing, why not split it onto two lines?

.level1 .level2 .level3 element1,
.level1 .level2 .level3 element2 {
    /*rules*/
}
Felix
A: 

I tend to go for as short a selector as possible. For example:

.level3 elem1,
.level3 elem2 {
    /* rules */
}

Unless you have a .levelX .level3 elem1 then the rule above won't clash with anything else. It's also quicker for the browser to parse because it doesn't have to check as many classes each time.

To be honest, if you have more than a couple of levels of classes then it may be worth checking your HTML structure and seeing if you can get rid of a few divs and the like.

DisgruntledGoat