Adding CSS to form or page with attachments

Last updated on
11 March 2021

Drupal 7 will no longer be supported after January 5, 2025. Learn more and find resources for Drupal 7 sites

This documentation needs work. See "Help improve this page" in the sidebar.

On the previous page we learned how to add css using the .info file and the drupal_add_css() function. You will recall that the major advantage to drupal_add_css() is that you can include CSS only on specific pages to reduce your page load. Unfortunately, if you have a lot of conditional rules for CSS inclusion, this can lead to complex logic in your template.php or in a hook_init() implementation. Thankfully, there's an easier way!

Adding css using #attached attribute

Drupal 7 introduced render arrays to improve the separation of content and markup. One of the elements of a render array is the #attached attribute. This attribute allows you to declaratively state what CSS needs to be included whenever that array is rendered into HTML.

Adding CSS to a cached block

If you add css using drupal_add_css() inside hook_block_view(), and then enable block cache, you will discover that the css will be included when the block is first rendered, but not if the block is cached. This is because the drupal_add_css() call only happens when the hook_block_view() function is called. Using #attached guarantees that the needed resource will be included as part of the rendering process even if the block is being pulled from cache. Under the hood, this happens via a call to drupal_process_attached(), which in turn calls drupal_add_css() for you.

Moving from drupal_add_css() to #attached

Initially, the code below will work, but if you enable block caching, or if you have defined your block to be cached in hook_block_info(), the my.css will fail to be included.

function foo_block_view($delta = '') {
  if ($delta === 'foo_delta') {
    drupal_add_css('path/to/my.css');
    $block = array(
      'subject' => t('Foo title'),
      'content' => t('Lorem ipsum text.'),
    );
    return $block;
  }
}

Changing the code to be cache-friendly is as simple as removing the call to drupal_add_css() and adding the #attached property with the resource included in the css property of the array you set as its value.

function foo_block_view($delta = '') {
  if ($delta === 'foo_delta') {
    $block = array(
      'subject' => t('Foo title'),
      'content' => array(
        '#markup' => '<p>' . t('Lorem ipsum text.') . '</p>',
        '#attached' => array(
          'css' => array(
            'path/to/my.css'
          ),
        ),
      ),
    );
    return $block;
  }
} 

You can add internal, external and inline css using this attribute.

We can also add css to the page in a similar way.

$content = array();
$content['#attached']['css'] = array(
  'path/to/my.css' => array(
    'group' => CSS_AGGREGATE_THEME,
    'weight' => 999
  ),
);
return $content; 

Tags

Help improve this page

Page status: Needs work

You can: