Yii 1.1: CSS Naming Conventions

24 followers

In this article, we introduce a set of CSS naming conventions that we have applied in several big projects and achieved success. The goal of these naming conventions is to eliminate the possibility of naming conflicts, facilitate debugging and maintenance, and to simplify the naming process.

Info: The naming conventions we introduce here may not be optimal to browsers. However, we believe that compared with the huge advantage it brings, its performance impact is negligible.

CSS Class and File Name

Use lower-case letters to name all CSS classes and files. And use dash characters to separate words in the name. For example, we may use names like widget-latest-comments, post.css.

Organizing CSS Files

Divide CSS styles into separate files to facilitate team work and future maintenance. The CSS files may be named according to the following rules:

  • global.css: this file contains global CSS styles that may be reused in different places.

  • layout.css: this file contains CSS styles used by layout views.

  • ControllerID.css: here ControllerID refers to any controller ID in the application. This means each controller may have its own CSS file named after its ID. For example, PostController may have a CSS file named post.css.

  • widget-WidgetClass.css: here WidgetClass refers to the class name of a widget that requires CSS styles. For example, LatestComments may use the name widget-latest-comments.css.

  • FeatureName.css: big features may have their own CSS files named after the feature names. For example, the Markdown content format may use the CSS file markdown.css.

  • Other needed CSS files, such as CSS frameworks.

Naming CSS Classes

In general, we should use CSS classes instead of IDs to style HTML elements. This is because the same ID cannot appear twice in the same XHTML page.

The naming conventions for CSS classes are as follows:

  • CSS classes that are meant to be shared should be prefixed with g-. For example, we can have names like g-submit-button, g-link-button. The declaration of the corresponding styles should be put in the aforementioned global.css file, and can use the simple syntax like the following:
.g-link-button {
   ...
}
  • Each action view file must have a root container that contains all its view content. The root container must declare a class named as the view path. For example, the post/index.php view file should content like the following:
<div class="post-index">
   ...view content here...
</div>
  • Declaration of the CSS styles of an action view should be put into the corresponding controller CSS file. Each declaration must be prefixed by the root container class. For example, to declare the CSS styles for an item element in the post/index view, we should put the following CSS styles in the post.css file:
/* in post.css file */
.post-index .item {
   ...
}
  • CSS class naming and style declaration for a widget view follow the similar rules for action views. For example, the LatestComments widget should use root CSS class name as widget-latest-comments, and declare its comment styles in the widget-latest-comments.css file like the following:
/* in widget-latest-comment.css file */
.widget-latest-comments .comment {
   ...
}
  • A layout view file should also have a root container named after the layout name with prefix layout-. For example, the main layout should use CSS class named as layout-main for its root container. To avoid naming conflict with the inserted view content, the CSS class of container elements in the layout may be prefixed with the root container class name. For example, the header section may use the name layout-main-header; the content section may use layout-main-content.

Including CSS Files

In development mode (when YII_DEBUG is true), every CSS file should be included in the main layout file.

In production mode, all CSS files should be merged and compressed into a single file. The file name should contain a timestamp (e.g. styles-201010221550.css).

By doing so, we can let the browser to cache the merged CSS file and thus eliminate the necessity of downloading CSS file each time.

Combining and Compressing CSS Files

Here we introduce a strategy on how to achieve the above goal.

First, we declare all CSS file names as an array in the application parameters in the application configuration.

Second, write a console command to combine and compress the CSS files. The YUI coompressor may be used for this purpose. The command will read the CSS file names from the application parameters, concatenate all file contents into a single file, and call YUI compressor to minify the CSS styles. The generated file should be named with a timestamp on it.

Third, modify the application main layout view by inserting the following code in the HTML head section:

<head>
    ......
    <?php if(Yii::app()->params['css.files.compressed']): ?>
    <link rel="stylesheet" type="text/css" 
          href="<?php echo Yii::app()->baseUrl.'/css/'
              . Yii::app()->params['css.files.compressed']; ?>" />
    <?php else: ?>
    <?php foreach(Yii::app()->params['css.files'] as $css): ?>
    <link rel="stylesheet" type="text/css" 
          href="<?php echo Yii::app()->baseUrl.'/css/'.$css); ?>" />
    <?php endforeach ?>
    <?php endif ?>
</head>

Note that in the above, we assume the CSS files are listed in the css.files application parameter. And if the files are combined and compressed, the resulting file name should be put in the css.files.compressed application parameter. The console command should modify the application configuration file to update the css.files.compressed parameter after it generates the combined and compressed CSS file.

Conventions for Naming jQuery Selectors

We can use the above CSS naming conventions in jQuery selectors in the application's javascript code. In particular, when selecting one or several elements using jQuery selectors, we should follow the similar rule for declaring CSS styles. For example, if we want to attach click handlers to all hyperlinks within news item blocks, we should use the following jQuery selectors:

$('.news-index .item a').click(function(){ 
    ... 
});

That is, a selector should be prefixed with the root container CSS class name (news-index in the above).

Total 4 comments

#5600 report it
marcovtwout at 2011/10/24 09:18am
Re: Improved inclusion of css files from Yii::app()->params['css.files']

Sounds like you can put that in an extension with a widget ;)

#5599 report it
Benjamin Bunse at 2011/10/24 04:47am
Improved inclusion of css files from Yii::app()->params['css.files']

When you use following code in the head section of the main layout file (instead of the code in the article) you can configure the inclusion of the css file regarding media and condition:

<?php if(Yii::app()->params['css.files.compressed']): ?>
    <link rel="stylesheet" type="text/css" 
          href="<?php echo Yii::app()->baseUrl.'/css/'
              . Yii::app()->params['css.files.compressed']; ?>" />
<?php else: ?>
    <?php foreach(Yii::app()->params['css.files'] as $css): ?>
    <?php
        if (is_array($css)) {           
            if (!isset($css["file"]))
                throw new CException("css file is declared as array in Yii::app()->params['css.files'] but [file] is not set", 0);
            echo sprintf('%3$s%5$s<link rel="stylesheet" type="text/css" href="%1$s"%2$s />%5$s%4$s',Yii::app()->baseUrl.$css["file"],($css["media"]?' media="'.$css["media"].'"':""),($css["condition"]?'<!--[if '.$css["condition"].']>':""),($css["condition"]?'<![endif]-->':""),"\n");
        } else {
            echo '<link rel="stylesheet" type="text/css" href="' . Yii::app()->baseUrl.'/css/'.$css . '" />';       
        }
    ?>
    <?php endforeach ?>
<?php endif ?>

The following params configuration example results in the default css files included by a clean Yii installation:

'params'=>array(
    'css.files'=> array(
            array("file"=>'/css/screen.css', "media"=>"screen, projection"),
            array("file"=>'/css/print.css', "media"=>"print"),
            array("file"=>'/css/ie.css', "media"=>"screen, projection", "condition"=>"lt IE 8"),
            array("file"=>'/css/main.css'),
            array("file"=>'/css/form.css'),
    ),
),
#5005 report it
ManInTheBox at 2011/09/05 11:31am
jQuery selector

Just a little note on jQuery selector using chained CSS classes.

Remove spaces around class name: .news-index.item a

#3049 report it
marcovtwout at 2011/03/10 07:03am
Typo

The "Naming CSS Classes"-part talks about "widget-latest-comment".

However, it is then used as both widget-latest-comment and widget-latest-comments.

It should be edited to whatever is intended.

Leave a comment

Please to leave your comment.

Write new article