horizon/doc/source/topics/styling.rst
Diana Whitten c9de52d6bb Dynamic Themes
Horizon themes are now configurable at a user level, through the use
of cookies. The themes that can be set are configurable at a
deployment level through settings.py. Horizon can be configured to
run with multiple themes, and allow users to choose which themes
they wish to run.

Django Compressor:
In order to support dynamic themes, each theme configuration must
be pre-compiled through the Django compressor. By making use of its
built in COMPRESS_OFFLINE_CONTEXT, we now return a generator to
create each of the theme's necessary offline contexts.

Templates:
Horizon themes allowed template overrides via their 'templates'
subfolder.  In order to maintain this parity, a custom theme template
loader was created.  It is run before the other loads, and simply
looks for a Django template in the current theme (cookie driven)
before diverting to the previous template loaders.

Static Files:
Horizon themes allowed static overrides of the images in
'dashboard/img' folder.  A template tag, 'themable_asset' was created
to maintain this parity. Any asset that is wished to be made themable,
given that it is located in Horizon's 'static/dashboard' folder, can
now be made ot be themable.  By making this a template tag, this
gives the developers more granular control over what branders can
customize.

Angular and Plugins:
By far, the trickiest part of this task, Angular and Plugins are
dynamic in the files that they 'discover'.  SCSS is not flexible in
this manner at ALL.  SCSS disallows the importation of a variable
name.  To get around this, themes.scss was created as a Django
template.  This template is the top level import file for all styles
within Horizon, and therefore, allows ALL the scss files to share a
common namespace and thus, can use shared variables as well as extend
shared styles.

Other:
This change is fundamental, in that it changes the method by which
Horizon ingests its SCSS files.  Many problems existing in the
previous implementation, in an effort to make Horizon flexible, its
SCSS was made very inflexible.  This patch corrects those problems.

Change-Id: Ic48b4b5c1d1a41f1e01a8d52784c9d38d192c8f1
Implements: blueprint horizon-dynamic-theme
Closes-Bug: #1480427
2016-02-25 09:49:43 -08:00

4.4 KiB

Styling in Horizon (SCSS)

Horizon uses SCSS (not to be confused with Sass) to style its HTML. This guide is targeted at developers adding code to upstream Horizon. For information on creating your own branding/theming, see customizing.

Code Layout

The base SCSS can be found at openstack_dashboard/static/dashboard/scss/. This directory should only contain the minimal styling for functionality; code that isn't configurable by themes. horizon.scss is a top level file that imports from the components/ directory, as well as other base styling files; potentially some basic page layout rules that Horizon relies on to function.

Note

Currently, a great deal of theming is also kept in the horizon.scss file in this directory, but that will be reduced as we proceed with the new code design.

Horizon's default theme stylesheets can be found at openstack_dashboard/themes/default/.

├── _styles.scss
├── _variables.scss
├── bootstrap/
    └── ...
└── horizon/
    └── ...

The top level _styles.scss and _variables.scss contain imports from the bootstrap and horizon directories.

The "bootstrap" directory

This directory contains overrides and customization of Bootstrap variables, and markup used by Bootstrap components. This should only override existing Bootstrap content. For examples of these components, see the Theme Preview Page.

bootstrap/
├── _styles.scss
├── _variables.scss
└── components/
    ├── _component_0.scss
    ├── _component_1.scss
    └── ...
  • _styles.scss imports the SCSS defined for each component.
  • _variables.scss contains the definitions for every Bootstrap variable. These variables can be altered to affect the look and feel of Horizon's default theme.
  • The components directory contains overrides for Bootstrap components, such as tables or navbars.

The "horizon" directory

This directory contains SCSS that is absolutely specific to Horizon; code here should not override existing Bootstrap content, such as variables and rules.

horizon/
├── _styles.scss
├── _variables.scss
└── components/
    ├── _component_0.scss
    ├── _component_1.scss
    └── ...
  • _styles.scss imports the SCSS defined for each component. It may also contain some minor styling overrides.
  • _variables.scss contains variable definitions that are specific to the horizon theme. This should not override any bootstrap variables, only define new ones. You can however, inherit bootstrap variables for reuse (and are encouraged to do so where possible).
  • The components directory contains styling for each individual component defined by Horizon, such as the sidebar or pie charts.

Adding new SCSS

To keep Horizon easily themable, there are several code design guidelines that should be adhered to:

  • Reuse Bootstrap variables where possible. This allows themes to influence styling by simply overriding a few existing variables, instead of rewriting large chunks of the SCSS files.
  • If you are unable to use existing variables - such as for very specific functionality - keep the new rules as specific as possible to your component so they do not cause issues in unexpected places.
  • Check if existing components suit your use case. There may be existing components defined by Bootstrap or Horizon that can be reused, rather than writing new ones.

Theme Preview Page

When the DEBUG <debug_setting> setting is set to True, the Developer dashboard will be present in Horizon's side nav. The Bootstrap Theme Preview panel contains examples of all stock Bootstrap markup with the currently applied theme, as well as source code for replicating them; click the </> symbol when hovering over a component.

Alternate Theme

A second theme is provided by default at openstack_dashboard/themes/material/. When adding new SCSS to horizon, you should check that it does not interfere with the Material theme. Images of how the Material theme should look can be found at https://bootswatch.com/paper/. This theme is now configured to run as the alternate theme within Horizon.