Friday

Double classes, double attributes

What happens if you have an HTML element that has TWO class attributes? For example, consider the following:

<div class="red" class="uppercase">Hello World!</div>
And let's define a couple styles:
.red {color: red;}
.uppercase {text-transform: uppercase;}
It turns out that only the FIRST class definition is respected by the browser; i.e. our example will be red, but NOT uppercase.

Testing

Using an online based tool (Litmus), I was quickly able to render my test page and verify this behavior in 11 browser versions, including IE6-9, FF 12, Chrome 18, Opera 11, Safari 5, and iPhone 4s. Below is a screenshot so you can (sort of) see.

Double Attributes

As a semi-related question, I thought it would be interesting to try targeting attributes instead of classes, so I tried this:

<div red uppercase>Hello World!</div>
And then changed my css to use (CSS2) attribute selectors:
.red, div[red] {color: red;}
.uppercase, div[uppercase] {text-transform: uppercase;}
And presto, my "Hello World!" becomes both red and uppercase. Interesting. Note that for this to be valid (only in HTML5 I believe), you'd want to add "data-" in front of each attribute, e.g. "data-red"; more info here: HTML5 Custom Attributes

Full demo with code

A different line-through color

Ever tried styling a line-through price so the strike color is different than the text? You know when you're looking at a sale online and the thing you're looking at is something like 20% off, and the merchant shows you a "before" price that has a horizontal line through it? This can be achieved in CSS using the line-through value on the text-decoration property. By default, it puts a line-through your text which is the same color as the font in that element. But what if you wanted a different color for the line than you have for the text (e.g. a red line through black text)? Turns out you can't style that separately in CSS; i.e. there's no support for something like line-through-color...But interestingly enough, you can add a bit of HTML structure around your text (price in our example), and this structure will allow you to style things uniquely. To wit:

Example HTML


    $515.00

Example CSS

.strikethrough {
    text-decoration: line-through;
    color: red;
}

.strikethrough * {
    color: #000;
}

Rendered Example

Buggy Behavior?

Pretty sweet. I wonder why it works this way though, because we are adding text-decoration to a container that doesn't actually have any text in it. Sure it's child has text, and we know that rules will be inherited by their children, but the line-through is working on the child DESPITE the child's inheritance of line-through. That is, the parent line-through is working on it's child's text, while the child's text is NOT actually applying a line-through at all. In fact, I can show this by setting my child to text-decoration: none, and yet the line-through still works on the parent. I find this odd, but oddly satisfying. This behavior is very nearly a bug in my opinion, though it's also a nice (maybe unintentional) feature. This goes way back to CSS1, so I think we're good. Here's some of my additional testing to see if this behaved differently with block or inline element combinations...turns out the answer is no. :-)

Support

Seems pretty good - I'm seeing very little support information for this feature on any of the usual boards (e.g. caniuse, quirksmode, sitepoint), but I've tested in FF, Chrome, IE7+, and all work similarly, and as expected. Mozilla claims support back to IE3 (IE3!), so it seems this is pretty ubiquitous in terms of support.

Wednesday

Generating quotes with CSS

You may have been made familiar with CSS generated content by reading blogs such as this one: Automatically Numbering Non-Lists...Or maybe not, whatever the case, there's other content generation we can do with CSS, like adding quotes.

I usually would just add a blockquote to my markup and add CSS generated content :before and :after my blockquote, like so:

blockquote:before {
    content: "“"; 
}
blockquote:after {
    content: "”";
}
And this works just fine; in fact, I might even argue that despite this blog post, this blockquote content approach may very well be the better approach. But, we're going to look at something new anyways; The CSS Quotes property.

Essentially, all this thing does is allow you to define your entire hierarchy of nested quotes to use throughout your site, and then call them in a nice, easy way. It's pretty straight forward, simply select your blockquote (and in my case, I'm also going to select the q element), and define your hierarchical quotes in left/right order:

blockquote, q {
    quotes: "1" "1b" "2" "2b" "3" "3b";
}
In my example, for the sake of illustration, I'm going to use a numbering system 1, 1b (1 for left and 1b right quotes), and continue that through to a 3rd level. I'm also going to add some styling to call out the 3 levels of quotes that I'm going to have in my HTML:
This is a super important quote. Here is a sub quote within my big quote. And now some lorem ipsum...
Now for my expanded CSS; you can see that to reference my quotes as defined, I'm going to use the :before and :after classes, and add my content, but instead of adding a string of "1", I can just say open-quote (and close-quote for the :after). This is possible because I've defined my quote content hierarchy in my quotes property:
blockquote {
font-family: sans-serif;
    margin: 1em;
}

blockquote, q {
    quotes: "1" "1b" "2" "2b" "3" "3b";
}

q {
    background: #fcc;
    padding: 3px;
    border-radius: 3px;
}

blockquote:before,
blockquote:after {
    content: open-quote;
    font-size: 2em;
    font-weight: bold;
    color: orange;
}

q:before,
q:after {
    content: open-quote;
    font-weight: bold;
    color: blue;
}

blockquote:after,
q:after {
    content: close-quote;
}

q q:before,
q q:after {
    font-weight: normal;
    color: green;
}
The end result will look like so:

I added a pink background around my inner q element to illustrate that our added quotes actually are included INSIDE our elements. Anyhow, sort of neat. Below is the full code...

Full Demo with Code

Final Thoughts

You could include the cite element in this discussion, and there are obviously a myriad of ways to render this stuff, so I'll leave it to you how you want to do that - but I think Smashing Magazine has a nice write up to take it from here.

Tuesday

Automatically Numbering Non-Lists

CSS allows us to add incremented number counts to repeated items on a page. Very similar to an ordered list, where by simply using appropriate HTML markup (e.g. Ordered List Example), you'd sort of magically get your list items numbered in order from 1 to N. But, what if you want to number things that AREN'T a list. Well, step one might be to make those things into an ordered list, but sometimes you don't have that level of control, or semantics suggest something different.

As an example, perhaps you have yourself a site that has a group of articles (which is a new element in HTML5 - Note that articles aren't necessarily like a news article, but rather more like an article of clothing - that is, it is something stands uniquely on its own.); and let's say you want to number your articles in the order in which they appear on the page. Instead of manually adding something like "Article 1", "Article 2", and so on, you could instead just use CSS to help you out.

Essentially, what we can do is select the elements we want to number (in our case, just all "article" elements), and utilize the counter-increment property to define a CSS variable that will contain a number that will increment for each of elements of our selection that is found. Then, we just need to use that variable by utilizing the content property, and include our counter variable. Our CSS will look like this:

article { 
    counter-increment: articleCount;
}
article:before {
    content: "Article " counter(articleCount);
}
Basically, I have named our article counter-increment variable "articleCount", and then using the :before selector, adding my content. I'm first adding the string "Article " (note the space in there), and then add the counter, with my articleCount variable. Presto.

Notice that I'm also defining two unique sections, within which I have my articles grouped. I then added a similar, but separate sectionCount, so I could illustrate how the counter-increment is unique by parent node. That being said, you could opt to use the counter-reset property. You can also chain your counts together:

Full Demo with Code

Full Demo with Code (chained variables)

Usage

It's important to note that IE6/7 don't support this functionality; see here. Though, SitePoint also suggests buggy support in Opera, so something to look out for.