Theming structure

One of the best things about Semantic UI is the amount of control it gives you over the styling of your project. It has an intelligent theming mechanism that lets you modify or override each component individually, and on different levels. This means you can pinpoint very accurately where to use the defaults and where to intervene.

There are 3 layers of theming: default, custom and site. Each layer has its own physical location in the Semantic UI folder structure. The layers are processed after another if you build SUI, meaning they will inherit all variables and styles from the layer below and implement their own adjustments on top of them.

This might sound a bit confusing at first, so pay attention 007:

Default theme

Location: semantic/src/themes/default/
Inherits from: semantic/src/definitions/

Don't edit anything in these locations!

This is obviously where the bulk of the styling lives. These styles are always processed; they serve as fallback. So even if you use a custom theme for one of your components, all the variables and CSS not overridden will still be included in semantic.css.

Custom themes

Location: semantic/src/themes

If you're not happy with the default styling, you can override it with a custom theme. See below how to activate a custom theme or create your own theme.

We can distinguish a couple of custom themes:

Semantic UI themes

Location: semantic/src/themes/**

Semantic UI comes with a few custom themes on board, but none of them are activated by default. To see them in action, check out the documentation. Each component has a theme switcher, so you can preview the available themes on the documentation page itself.

Inside a theme, the file structure dictates which parts of the default styling are being altered. So you don't need to replace the entire default theme. Looking at the 'Material' theme below, you can see how it only applies to menus, buttons, headers, icons, dropdowns and modals. All other components will fall back to their defaults.

├── material
│   ├── assets
│   │   └── fonts
│   │       ├── icons.eot
│   │       ├── icons.svg
│   │       ├── icons.ttf
│   │       ├── icons.woff
│   │       └── icons.woff2
│   ├── collections
│   │   ├── menu.overrides
│   │   └── menu.variables
│   ├── elements
│   │   ├── button.overrides
│   │   ├── button.variables
│   │   ├── header.overrides
│   │   ├── header.variables
│   │   ├── icon.overrides
│   │   └── icon.variables
│   ├── globals
│   │   ├── site.overrides
│   │   └── site.variables
│   └── modules
│       ├── dropdown.overrides
│       ├── dropdown.variables
│       ├── modal.overrides
│       └── modal.variables

Romanesco theme

Location: semantic/src/themes/romanesco/

The Romanesco platform also comes with a customized theme. It contains a lot of small tweaks and additions to make sure all content looks balanced and neat when viewed in the browser.

If you want to change anything in this theme, please consider forking the repository and create a pull request on Github with your fixes.

Your own theme

Location: semantic/src/themes/your-theme/

You can also create your own themes. If you are working on a web project where design elements will be reused in the future, this is definitely a good idea. This way, you can maintain the styling of different projects through a centralized theme. The Romanesco theme mentioned above is a good example.

The Site folder

Location: semantic/src/site

The third theming layer is inside the Site folder.

The changes you put in here are only applied to your project, will always be loaded and will override anything in the theme files below.

This is regardless of which theme you assigned to a component in theme.config. The idea is that any change specific to the project (logo, branding, custom components) will be located in this site folder.

Also: if you don't want to bother with reusing styles at all, then the site folder is the place to work from.

Global styles

Location: semantic/src/site/global

Inside your site (and optionally theme) folder, there are 2 files that deserve

Activating a theme

OK, so now you know where all the themes are located, but how does Semantic UI know which themes you want to use? The key is in the following folder:

semantic/src/theme.config

If you open theme.config, you'll see a list of all the available elements inside Semantic UI. By default all of them will be set to 'default', but as you may have guessed already, you can enter any available theme you like here to override the default one.

Here's a typical custom theming configuration inside theme.config:

/* Global */
@site       : 'romanesco';
@reset      : 'romanesco';

/* Elements */
@button     : 'romanesco';
@container  : 'romanesco';
@divider    : 'romanesco';
@flag       : 'default';
@header     : 'romanesco';
@icon       : 'default';
@image      : 'romanesco';
@input      : 'default';
@label      : 'default';
@list       : 'romanesco';
@loader     : 'default';
@placeholder: 'default';
@rail       : 'default';
@reveal     : 'default';
@segment    : 'romanesco';
@step       : 'romanesco';

/* Collections */
@breadcrumb : 'default';
@form       : 'romanesco';
@grid       : 'romanesco';
@menu       : 'romanesco';
@message    : 'default';
@table      : 'romanesco';

/* Modules */
@accordion  : 'romanesco';
@checkbox   : 'default';
@dimmer     : 'default';
@dropdown   : 'romanesco';
@embed      : 'default';
@modal      : 'default';
@nag        : 'default';
@popup      : 'default';
@progress   : 'default';
@rating     : 'default';
@search     : 'default';
@shape      : 'default';
@sidebar    : 'default';
@sticky     : 'default';
@tab        : 'romanesco';
@transition : 'default';

/* Views */
@ad         : 'default';
@card       : 'romanesco';
@comment    : 'romanesco';
@feed       : 'timeline';
@item       : 'default';
@statistic  : 'default';

Creating a theme

Creating a theme is fairly straight-forward. Semantic UI will be looking for themes inside the 'semantic/src/themes/' folder. You can create a new folder there, but it's easier to just copy and rename the 'default' folder. Then you'll see that all the components will have the correct folder structure already.

Each component is represented by 2 files: a .variables file and a .overrides file. The file extensions speak for themselves here: all your custom CSS will go into .overrides and if any variables need to be changed, just add them to .variables.

Variables greatly increase your theming abilities. Because Semantic UI uses over 3000 variables, most of what you would want to change can be tweaked simply by adding a line with a different value in your .variables file. To see which variables are available for each component, check out their .variables file in the default theme. In your custom theme, you only need to define the variables that you want to change.

For example, if you want to tweak all buttons inside your project, you can add something like below.

To semantic/src/themes/your-theme/elements/buttons.variables file:

// Give buttons slightly more bottom padding
@shadowOffset: 0.1em;

// Create a small 3D effect
@shadowDistance: 0.1em;

And to the semantic/src/themes/your-theme/elements/buttons.overrides file:

// Content buttons are too close to top content
#content * + .ui.button {
	margin-top: 0.5em;
}

Don't forget to set the @button variable to your theme name inside theme.config and run gulp build again.

Since Semantic UI uses LESS for pre-processing you could use LESS functions and mixins here if you want, but I'd advice against that. It will be more difficult to convert it later, for example if future versions of Semantic UI would switch to something like native CSS variables. Straight up CSS will work best here.

Long story short

So let's recap: Semantic UI uses a 3-layered theme structure to adjust the styling. The bottom layer contains the defaults. Without any tinkering from your side, these will always be loaded. If you are not satisfied with any of the defaults, you can turn to custom themes for help. This is the second layer. Custom themes are presets that change the defaults in a certain way, and they are applied per component. So if you are happy with the default grid, but not with the default buttons, you can change the theme for all buttons in your project. Custom themes are assigned in the theme.config file.

When you install Semantic UI, you'll see that each component will already have a few alternative themes available, with names like "chubby", "material" or "github". These names hint to how the appearance of that component will be altered. If you want to customize things further, you are free to create as many themes as you need, in the same manner.

And if you don't need to reuse any of your custom styling outside of your project, then you can just stick to the Site folder for adding and maintaining your styles. This folder is created when you install SUI and anything inside will be processed, regardless of whatever theming is defined below. Your very own CSS sledgehammer!

Further reading

https://semantic-ui.com/usage/theming.html
http://learnsemantic.com/themes/overview.html
http://learnsemantic.com/themes/creating.html