tags:

views:

869

answers:

3

Without using Javascript, is there a way to make a CSS property toggle on and off through nested elements.

The problem I'm trying to solve is that I have a number of tags and classes which make some text italic (<em>, <blockquote>, <cite>, <q>, <dfn>, and some other classes), and when one of these is inside another one of these, the italicisation needs to toggle.

<blockquote>
    And so the man said, <q>That's not from <cite>Catcher In The Rye</cite>, dear
    fellow!</q>, can you believe that?!
</blockquote>

Should render as:

And so the man said, "That's not from Catcher In The Rye, dear fellow!", can you believe that?!

The CSS I've got for this is getting a bit messy:

q, em, dfn, cite, blockquote {
    font-style: italic;
}
q q, q em, q dfn, q cite,
em q, em em, em dfn, em cite,
dfn q, dfn em, dfn dfn, dfn cite,
cite q, cite em, cite dfn, cite cite,
blockquote q, blockquote em, blockquote dfn, blockquote cite {
    font-style: normal;
}

...and I'm pretty sure that won't even work past one level of nesting (as in my example).

Is there a way I can do this without have to list every permutation of the tags?

A: 

I would manage that with a script that generates the necessary nesting rules for each permutation. It's the only way that I would not go insane maintaining it.

Geoff
+1  A: 

I couldn't tell you which browsers (if any) implement the CSS3 :not pseudo-class, but if we see it supported sometime it seems like we can do:

q:not(q, em, dfn, cite, blockquote), 
em:not(q, em, dfn, cite, blockquote), 
dfn:not(q, em, dfn, cite, blockquote), 
cite:not(q, em, dfn, cite, blockquote), 
blockquote:not(q, em, dfn, cite, blockquote) { font-style: italic; }

It's anyones guess as to how browsers will implement this when they do, so it might not work more than 2 levels deep (like your example).

Other than that, unfortunately I can't think of another pure CSS solution.

Eric Wendelin
A: 

You say you have all sorts of elements that needs displaying as italic, but once nested they need to break previous italication. Forgive me for saying, but I am truly wondering if one should really want such behavior.

Allow me to explain myself: you have different markup such as a quote, citation, emphasis etc. When used nested, the emphasis inside a quote should really have a different meaning than when used outside the quote. Therefore, default css rules apply to all that lies underneath. And therefore, I do not understand the desire of flattening your meaningful nested markup to italic and non-italic, because it hides the underlying meaning of the contents at hand (because similar formatting will be applied to different meaningful parts of the document).

My recommendation would be to either:

  • Assume that your markup is there for a reason, so leave the styling as it is. An emphasis nested within a blockquote should always have the styling of its ancestor elements, because there is a reason for this nesting and it should not be hidden for the user in a visual way
  • Go over the requirements of your document and see if you really want such nesting. If not, a generic HTML editor might not be sufficient to your needs and you might be better off using an xml format that validates to a certain schema that, in your case, would forbid certain element usage within others. Then use an xml editor such as Xopus or XmlSpy to edit your document.

Sorry if this is not a direct solution to your question, but I hope to be able to give you another perspective towards the problem and perhaps see that there might not be a problem at all. Good luck!

Martin Kool