CSS for Pages

The CSS methods within the {{ _page }} object allow you to output CSS in your template or set CSS files and inline CSS to be included on certain pages. Often the core CSS for a site is set within the site template or snippet, but there are times when certain CSS is needed for specific pages.

Some example scenarios include:

  • You may have CSS specific for a type of page, like a store product page
  • You may need to include CSS for a collection widget slideshow

You can include CSS files or inline CSS in any type of template. You can output the CSS in any template as well, although it's traditionally set in a site template or site snippet.

CSS groups

Including CSS files

Including inline CSS

Register files as being used

Outputting CSS

Accessing CSS files and inline CSS

Test to see if a file has been set

CSS groups

When you set and output CSS files and/or inline CSS you can organize your CSS in groups. A simple scenario would be to have some CSS that you want to include at the end of the HTML and some CSS to include in the <head> section of the HTML.

The default group is 'default'. If no group is passed when adding or outputting CSS then the 'default' group will be used.

Below is an example of setting a CSS file to be included in the 'footer' group.

{% do _page.addCss('/path/to/file.css', {'group': 'footer'}) %}

You can then output it in your template with

{{ _page.css('footer') }}

You can call the groups whatever you want as long as it's an alphanumeric string. 'footer' is just an example used here.

Including CSS files

You use the {% do _page.addCss() %} method to include page-specific CSS files in your templates.

You do not need to do this for any core CSS files needed. You can simply put the <link type="text/css" rel="stylesheet" href="/path/to/file.css"> tags in your template like normal.

Examples

Include a CSS file to the default group.

{% do _page.addCss('/path/to/file.css') %}

This will output the following for {{ _page.css() }}

<link type="text/css" rel="stylesheet" href="/path/to/file.css">

Include a CSS file to a group named bottom.

{% do _page.addCss('/path/to/file.css', 'bottom') %}

The following is equivalent:

{% do _page.addCss('/path/to/file.css', {'group': 'bottom'}) %}

Those will output the following for {{ _page.css('bottom') }}

<link type="text/css" rel="stylesheet" href="/path/to/file.css">

Setting link tag attributes

You can also set attributes for the <link> tag when adding a CSS file. Any valid attribute can be set.

{% do _page.addCss('/path/to/file.css', {'media': print, 'class': 'myClass'} %}

This will output the following for {{ _page.css() }}

<link type="text/css" rel="stylesheet" href="/path/to/file.css" media="print" class="myClass">

{% do _page.addCss('/path/to/file.css', {'media': print, 'group': 'head'} %}

This will output the following for {{ _page.css() }}

<link type="text/css" rel="stylesheet" href="/path/to/file.css" media="print">

Preloading CSS files

For performance reasons you may want to load CSS files asynchronously. One way to do that is to preload the CSS file. Below is the HTML to do that.

<link rel="preload" href="path/to/mystylesheet.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="path/to/mystylesheet.css"></noscript>

You could manually do that with the following code:

{% do _page.addCss('/path/to/mystylesheet.css', {'rel': 'preload', 'as': 'style', 'onload': 'this.onload=null;this.rel=\'stylesheet\''}) %}

And then to support instances of no Javascript support you would need to include the <noscript> tag.

To make this easier you can simply set the 'preload' attribute to be true.

{% do _page.addCss('/path/to/mystylesheet.css', {'preload': true}) %}

That will set the appropriate attributes on the <link> tag for the stylesheet as well as include the <noscript> code.

Prepending files

If you need a specific CSS file to be first then you can do the following.

{% do _page.prependCss('/path/to/file.css') %}

You can assign the CSS file to a group and/or set any <link> tag attributes just like the _page.addCss() method.

{% do _page.prependCss('/path/to/file.css', {'media': print, 'group': 'head'} %}

Including inline CSS

In addition to setting page-specific CSS files you can also set page-specific inline CSS.

There are two ways to add inline CSS to a page. For one-line snippets, you can use the {% do _page.addinlineCss() %} method. For longer code you would use the {% inlinecss %} {% endinlinecss %} tags to capture any inline CSS to include on the page.

If you add the exact same inline CSS multiple times it will only be outputted once within a group. This is useful if you have a component that is used multiple times on a page. By only outputting the unique inline CSS once you don't have to worry about redundant styles getting outputted.

Including short CSS

Below are some examples of including a short snippet of CSS. Just like including a CSS file you can specify the group to include the CSS in as well as specify any <style> tag attributes.

Simple example.

{% do _page.addInlineCss('body {color: red;}') %}

That will output the following for {{ _page.css() }}

<style>
body {color: red;}
</style>

Included some inline CSS and assign it to the footer group.

{% do _page.addInlineCss('body {color: red;}', 'footer') %}

The following is equivalent.

{% do _page.addInlineCss('body {color: red;}', {'group': 'footer'}) %}

Those will output the following for {{ _page.css('footer') }}

<style>
body {color: red;}
</style>

Include some inline CSS and add some attributes to the <style> tag and assign to the head group.

{% do _page.addInlineCss('body {color: red;}', {'class': 'my-class', 'group': 'head'} %}

That will output the following for {{ _page.css('head') }}

<style class="my-class">
body {color: red;}
</style>

Include larger blocks of inline CSS

You would use the {% inlinecss %} {% endinlinecss %} tags to capture any inline CSS to include on the page.

Below is a simple example.

{% inlinecss %}
    body {color: red;}
    p {margin: 10px 0; outline: 1px solid blue; }
{% endinlinecss %}

That will output the following for {{ _page.css() }}

<style>
    body {color: red;}
    p {margin: 10px 0; outline: 1px solid blue; }
</style>

You can specify a group to assign the CSS to.

{% inlinecss group="footer" %}
    body {color: red;}
    p {margin: 10px 0; outline: 1px solid blue; }
{% endinlinecss %}

That will output the following for {{ _page.css('footer') }}

<style>
    body {color: red;}
    p {margin: 10px 0; outline: 1px solid blue; }
</style>

Any other tag attributes other than 'group' are included as attributes for the <style> tag.

{% inlinecss group="footer" id="footer-inline-js" %}
    body {color: red;}
    p {margin: 10px 0; outline: 1px solid blue; }
{% endinlinecss %}

That will output the following for {{ _page.css('footer') }}

<style id="footer-inline-js">
    body {color: red;}
    p {margin: 10px 0; outline: 1px solid blue; }
</style>

Prepending Inline CSS

If you need a certain block of inline CSS to appear first in it's group then you can prepend the CSS.

{% do _page.prependInlineCss('body {color: red;}') %}

You can assign the CSS file to a group and/or set any <style> tag attributes just like the _page.addInlineCss() method.

{% do _page.prependInlineCss('body {color: red;}', {'class': 'my-class', 'group': 'head'} %}

You can also prepend larger chunks of CSS code with the {% inlinecss %} {% endinlinecss %} tags by adding prepend="yes" as an attribute on the {% inlinecss %} tag.

{% inlinecss prepend="yes" group="footer" id="footer-inline-js" %}
    body {color: red;}
    p {margin: 10px 0; outline: 1px solid blue; }
{% endinlinecss %}

Register files as being used

You can register a CSS file as being used even if it's not outputted with the {{ _page.css() }} method.

{% do _page.registerCss('/path/to/file.css') %}

A few possible reasons for doing this include:

  1. You might be hard coding the <link> tag for the file in your template and you don't want another template to include that file.
  2. You may be using a library like loadCSS to asynchronously load some of your CSS files.

For the later reason, the register method is useful because it allows you to test if a file is being used even if it's not included in the output of CSS files. Below is an example showing testing for a file. If it's not part of the list of CSS files used on the page then some inline Javascript is added to load the file and then the file is registered.

{% if _page.hasCss('/path/to/file.css') == false %}
    {% inlinejs %}
        loadCSS('/path/to/file.css');
    {% endinlinejs %}
    {% do _page.registerCss('/path/to/file.css') %}
{% endif %}

Outputting CSS

The {{ _page.css() }} method is used to output CSS. It will output any CSS files and/or inline CSS that is assigned to the group.

Output any files and/or inline CSS assigned to the default group.

{{ _page.css() }}

Output any files and/or inline CSS assigned to the footer group.

{{ _page.css('footer') }}

If no CSS files or inline CSS have been assigned to the group, then nothing will be outputted.

You can add CSS files or inline CSS after the {{ _page.css() }} tags are set in your templates. The {{ _page.css() }} tags are processed after the entire template and any included code is processed.

Output only files

If you wanted to only output CSS files then you would do the following:

{{ _page.cssFiles() }}

Output any files assigned to the footer group.

{{ _page.cssFiles('footer') }}

Output only inline CSS

If you wanted to only output inline CSS code then you would do the following:

{{ _page.inlineCss() }}

Output any inline CSS code assigned to the footer group.

{{ _page.inlineCSS('footer') }}

Set attributes

You can set attributes to be added to all <link> and <style> tags when outputting the CSS by passing a hash of attributes as the second parameter.

{{ _page.css('group-name', {'class': 'myClass'}) }}

{{ _page.cssFiles('group-name', {'class': 'myClass'}) }}

{{ _page.inlineCss('group-name', {'class': 'myClass'}) }}

Accessing CSS files and inline CSS

You can access any CSS files or inline CSS. For example, you can loop through files and update their attributes.

NOTE: You will only be accessing any files or inline code that has been added at that point in the template rendering process.

Access CSS files

{% set files = _page.css.files %}

Loop through files and set tag attributes

{% set files = _page.css.files %}
{% for file in files %}
    {% set file.class = 'myClass' %}
{% endfor %}

{% for file in _page.css.files %}
    {% set file.class = 'myClass' %}
{% endfor %}

Access inline CSS

{% set inline = _page.css.inline %}

Loop through inline CSS and set <style> tag attributes

{% set inline = _page.css.inline %}
{% for code in inline %}
    {% set code.class = 'myClass' %}
{% endfor %}

{% for code in _page.css.inline %}
    {% set code.class = 'myClass' %}
{% endfor %}

Test to see if a file has been set

You can test and see if a CSS file has been set yet and use that to determine if you want to add some other code.

NOTE: You don't need to do this to ensure that there are no duplicate references to any CSS files. The system automatically handles duplicates to only include any CSS files once within a group.

{% if _page.hasCss('/path/to/file.css') == false %}
    {# Do something here #}
{% endif %}

The path to the file must be the full path to the file from the site root and should start with / , http:// or https://.

You can use the theme_url or file_url filters when testing or registering files.

{% if _page.hasCss('/path/to/file.css'|theme_url) == false %}
    {# Do something here #}
    {% do _page.registerCss('/path/to/file.css'|theme_url) %}
{% endif %}
{% if _page.hasCss('/path/to/file.css'|file_url) == false %}
    {# Do something here #}
    {% do _page.registerCss('/path/to/file.css'|file_url) %}
{% endif %}