Monday, August 2, 2010

CSS Feature Request, Style Inheritance

Being a web developer for the Government of Canada, I gained a lot of experience with creating corporate templates to be shared and used by multiple web sites. When creating such templates, it is really important to ensure that on top of displaying correctly, that it's easy to customize and maintain. While trying to find the best possible way to achieve this goal, I found myself wishing that CSS had one of Object Oriented Programming's (OOP) functionality : Inheritance.

In CSS there is already a concept called inheritance but its way different than the concept used in OOP. CSS inheritance is the characteristic of DOM objects (HTML tags) to use their parent's style. For example, when a div tag specifies its text color to red, child tags will use that color unless specified otherwise. The type of inheritance I wish for is the ability to define styles in one class and reuse them in another class.

Using this type of inheritance would significantly help web developers create flexible and easy to use templates. One of the main scenario I would such feature would be to create a color palette. By defining generic classes for color palette, the entire web site color scheme can be modified by changing these classes. This can be very handy for a big web site that use the same template for each section but uses different color scheme. Each section could be using the master stylesheet and override these generic class in a custom stylesheet.

This feature would have the benifit of being totally unintrusive. Web developpers would not be forced to use it and it would not conflict with any existing CSS. The following example illustrates using CSS style inheritance to define a color palette. Note that I use the keyword 'reference' when demonstrating the syntax to avoid confusion with CSS DOM inheritance.

Example

Consider this template as an example :


HTML

Below is a simplification of the code for this template

<body>
    <div id="banner">
        <p>Banner Text</p>
    </div>
    <div id="Breadcrumbs">
        <ol>
            <li><a href="">Home</a></li>
            <li><a href="">Level 1</a></li>
        </ol>
    </div>
    <div id="content">
        <h1>Title</h1>
        <div class="column1_2">
            <p>Column 1</p>
        </div>
        <div class="column2_2">
            <p>Column 2</p>
        </div>
        <div class="column1_1">
            <p>Some Content</p>
        </div>
    </div>
    <div id="left">
        <h2>Section 1</h2>
        <ul>
            <li><a href="">Item 1</a></li>
            <li><a href="">Item 2</a></li>
        </ul>
    </div>
    <div id="right">
        <h2>Section 1</h2>
        <div>
            ...
        </div>
    </div>
    <div id="footer">
        <ul>
            <li><a href="">Home</a></li>
            <li><a href="">Help</a></li>
            <li><a href="">Site Map</a></li>
        </ul>
    </div>
</body>

CSS

The usual CSS for the template would look like this:
#banner{
    background-color:#363;
    color:#FFF;
    text-align: center;
    font-size: 120%;
}

[…]

.column1_2, .column2_2, .column1_1 {
    border-color:#363;
    border-style:solid;
}

.column1_2, .column2_2{
    border-width:1px;
}

.column1_1 {{
    border-width:3px;
}

[…]

#left h2, #right h2{
    background-color:#363;
    color:#FFF;
    margin-bottom:0.2em;
}

#left ul, #footer ul{
    list-tyle-type:none;
    margin:0;
    padding:0;
}

#left ul{
    background-color: #CC9;
    color: #000;
}

#footer ul{
    background-color:#363;
    color:#FFF;
}

#footer ul li{
    float:left;
}

New CSS

In the original CSS the color #363 is repeated several times. The following code illustrates how the CSS could look like with style inheritance.
/* COLOR SWATCHES */

.primary-solid{
    background-color:#363;
    color:#FFF;
}

.primary-border{
    border-color:#363;
}

.secondary-solid{
    background-color:#363;
    color:#FFF;
}

/* END OF COLOR SWATCHES */

#banner{
    reference: primary-solid
    text-align: center;
    font-size: 120%;
}

[…]

.column1_2, .column2_2, .column1_1 {
    reference: primary-border
    border-style:solid;
}

.column1_2, .column2_2{
    border-width:1px;
}

.column1_1 {{
    border-width:3px;
}

[…]

#left h2, #right h2{
    reference: primary-solid
    margin-bottom:0.2em;
}

#left ul, #footer ul{
    list-tyle-type:none;
    margin:0;
    padding:0;
}

#left ul{
    reference: secondary-solid
}

#footer ul{
    reference: primary-solid
}

#footer ul li{
    float:left;
}

This concludes my first post. Thank you very much for reading and do not hesitate to give me feedback.

Laurent