This is Underdark's style framework. It aims for easy usage for developers that are better off if they don't need to think about the style of their document or application that much.

The purpose of this CSS framework is to be able to quickly build web tools that scale and look nice. It is mostly used for in-house projects but is also very suitable to use for prototypes or other projects.

This CSS framework should serve as a basis for generic web pages and applications. By allowing the re-use of html we foster the re-use of backend templates and code. Having moved all styling towards the CSS, and keeping the CSS-based on the hierarchy instead of class names or indices there’s no reason to update the html for most cases.

Most HTML documents have a very similar structure. Based on that common structure we make assumptions.


By minimising the amount of introduced classes and instead relying on the already available hierarchy of the DOM to introduce styling we allow the HTML to be written once and reused continuously by different projects.

This CSS framework may not be suitable for every project. By assuming a certain markup structure we can apply general styles. The HTML used in combination with our CSS should be structured in a specific way.

SMACCS is our style guide.

Browser support

We aim for the most recent browsers to keep up with current developments, but obviously most features will work on most browsers that support CSS3.

Please report any problems experienced using Underdark CSS in these browsers.



The structure of Underdark CSS is loosely based on Scalable and Modular Architecture for CSS (SMACSS).

Since the style rules rely heavily on cascading, the files should always be loaded in the right order:


Elements should not have any other default styles set other then those in base.

Submit type

Both the input element and the button element can be of type submit.




Form markup can be quite complex. If forms conform to our assumptions they get nicely styled.

Hidden input

Hidden inputs should always be placed at the top of the form, otherwise some CSS selectors won't select the correct elements leading to unexpected results, like a misplaced submit button/input.


<link href="//" rel="stylesheet">
<link href="//" rel="stylesheet">
<link href="//" rel="stylesheet">
<link href="//" rel="stylesheet">

After that you may load your own module and theme styles:

<link href="/styles/module.css" rel="stylesheet">
<link href="/styles/theme.css" rel="stylesheet">


To write good documents, you need a good sense of how to structure it. It is a good idea to learn about the norms.

Common structures.


We start by showing what markup hierarchies are expected. The examples don't show the complete hierarchy, only the body is included to keep it simple.

Unless mentioned otherwise, all child elements must be direct descendants of their parent element.

All elements may be omitted. When used correctly and without any additional overriding of the styles these structures should always like nice.

Basic layout
  1. body
    1. header
    2. main
    3. footer
Layout with aside/nav
  1. body
  2. header
  3. main
    1. aside/nav
    2. article/section
  4. footer
Header layout
  1. header
    1. div.logo
    2. form.login
    4. nav
    5. button.toggle
Footer layout
  1. footer
    1. nav
      1. ul
    2. div.copyright
      1. p
Footer layout
  1. footer
    1. nav
      1. section
        1. ul

As per HTML specification sectioning elements should contain a heading.

Form layout

Forms should have a specific markup when used with Underdark CSS. There are a lot of ways to markup form content that HTML allows.

To discriminate between

Logo in header
  1. div.logo
    1. a
    2. p

Where the a contains the name of the project and optionally the p contains a subtitle or pay-off.


Except for certain wrapper divs, the mentioned elements may be omitted.


A Base rule is applied to an element using an element selector, a descendent selector, or a child selector, along with any pseudo-classes. It doesn’t include any class or ID selectors. It is defining the default styling for how that element should look in all occurrences on the page.

Base styles include setting heading sizes, default link styles, default font styles, and body backgrounds. There should be no need to use !important in a Base style. – SMACCS


The base styles consists of Normalize.css and some sane defaults.

We specify a default font size on the HTML element.

Body should have a almost-black and a white background color.


form {
  margin: 0;
  padding: 0;

a {
  color: #039;
a:hover {
  color: #03f;


CSS, by its very nature, is used to lay elements out on the page. However, there is a distinction between layouts dictating the major and minor components of a page. The minor components—such as a callout, or login form, or a navigation item—sit within the scope of major components such as a header or footer. I refer to the minor components as Modules and will dive into those in the next section. The major components are referred to as Layout styles. – SMACCS

The layout styles define the page layout.


body > header,
body > article,
body > footer {
  width: 60rem;
  margin: auto;

body > article {
  border: solid #ccc;
  border-width: 1px 0 0;


As briefly mentioned in the previous section, a Module is a more discrete component of the page. It is your navigation bars and your carousels and your dialogs and your widgets and so on. This is the meat of the page. Modules sit inside Layout components. Modules can sometimes sit within other Modules, too. Each Module should be designed to exist as a standalone component. In doing so, the page will be more flexible. If done right, Modules can easily be moved to different parts of the layout without breaking.

When defining the rule set for a module, avoid using IDs and element selectors, sticking only to class names. A module will likely contain a number of elements and there is likely to be a desire to use descendent or child selectors to target those elements.

Use child or descendant selectors with element selectors if the element selectors will and can be predictable. Using .module span is great if a span will predictably be used and styled the same way every time while within that module. – SMACCS

Underdark modules

Underdark modules are very generic modules, like for example pagination. To use Underdark module styles, load module.css from

Project-specific modules

Module styles can be loaded from and from your own project as well. Project-specific module styles should not override Underdark module styles. Only theme.css should override the Underdark module styles. You may also put all your module styles in your theme file if no further separation is really needed.

.module > h2 {
  padding: 5px;

.module span {
  padding: 5px;
With generic element
/* Folder */
.folder > span {
  padding-left: 20px;
  background: url('icon.png');
With pseudo class
/* Folder */
.folder > span:first-child {
  padding-left: 20px;
  background: url('icon.png');
With class name
/* Folder */
.folder > {
  padding-left: 20px;
  background: url('icon.png');
.pod {
  width: 100%;
.pod input[type="text"] {
  width: 50%;
aside .pod input[type="text"] {
  width: 100%;


Theme Rules aren't as often used within a project and because of that, they aren't included as part of the core types. Some projects may have a need for them, though, as we did when working on Yahoo! Mail.

It is probably self-evident but a theme defines colours and images that give your application or site its look and feel. Separating the theme out into its own set of styles allows for those styles to be easily redefined for alternate themes.

Themes can affect any of the primary types. It could override base styles like default link colours. It could change module elements such as chrome colours and borders. It could affect layout with different arrangements. It could also alter how states look. – SMACCS


With the theme file a domain-specific style can be applied. Always load theme.css last.

Theme styles can also be cascading, e.g. you can load our global theme first and your own theme second:

<link href="//" rel="stylesheet">
<link href="/styles/theme.css" rel="stylesheet">


A theme can be very light weight but also can dramatically extend the onderlying styles. By including Underdark CSS and writing some CSS on top of it, you can have the robustness of our well-tested code and add your own flavours.

From the beginning, we adopted SMACSS as a convention for writing our CSS. For those who are new to SMACSS, you should give it a quick read.

You should respect the selectors used in the other CSS files and write your own on top of them to make them more specific, e.g.:

/* layout.css */
body > header > li > ul {
  /* Some style declarations */
/* theme.css */
body > header > li > ul {
  /* Overriding style declarations */
body > header > li > ul > li {
  /* Project-specific style declarations */

Underdark CSS relies heavily on DOM hierarchy. Theme files should also conform to this as shown in the above example.


Found out where styles are declared by inspecting the live DOM. Look for the correct scope and extend from there.

For example are your styles ment to be applied on all form elements, only on a specific page or only in a specific module? Tip: think specific first and try to make it as less specific as possible. When you find that other elements are inadvertently effected, take a step back and make it more specific again. Use the > combinator (specific, direct children) as much as possible to control the scope.




Don't try to force content into an <aside>, if it's not tangentially related to the article then it shouldn't be there.

HTML5 Doctor

When using an aside it may be a good idea to think about specifying a type by setting a class. The following types are examples of optionally added semantic value by using a class name:

Class name Semantic value
background Background information
legend Legend
data Factual data
glossary Glossary of terminologies
partners Partners

For more information, see

Hidden elements

Hiding elements can be done in several ways. Here is a set of rules to so you can most effectively:

The hidden attribute
The hidden class
The hidden type
This way must only be used on input elements.

Non-semantic naming

No matter how important it is to use names that describe the content, sometimes it is inevitable to deviate from this good practise. For example when you need to traverse up element tree, which is impossible with CSS up to now.


The files can be minified and/or zipped on request. Below only base.css and menutoggle.js are used as an example. All other stylesheets and cript files can be loaded the same way. All URLs start with






The readme explains the use of the stylesheets.

The tests contain a set of examples, snippets and possibly known bugs from various browsers to see if everything works as planned. These tests can be viewed in a browser.

The changelog mentions all changes.

Note: using stable in production is not recommended, since stable will point to a newer version in the future, which might break your layout.


Below only the non-minified, non-zipped base.css and menutoggle.js are used as an example. Minified and/or zipped files can be loaded the same way.



The version number is also mentioned in the header in the file itself.

The changelog only mentions changes since the previous release.

File naming convention for combined files

Underdark CSS uses the following naming convention:


Where .{layers} is optionally .b, .bl, .blm or .blmt, and {ver.sion} is 0.1 or up.


Put this line in the <head> of your HTML document to load all style layers (excluding the default theme) combined and minified:

<link href="//" rel="stylesheet">

For example use this line to load only base and layout layers combined and minified:

<link href="//" rel="stylesheet">


We use a specific update strategy to keep sites using Underdark CSS from breaking, If you use a specific version we intent to only update issues within that version and not introduce any changes that would require html files to be changed.

Changes between versions will be documented and their purpose explained so you can update your HTML accordingly.


Tests are available for all elements, all layouts and all modules.


All Underdark CSS styles of elements, layout and modules can be tested.

A test page containing all HTML 5 elements can be used to check if all Underdark CSS base styles are okay. See Only the Underdark CSS base styles are loaded.
Test pages demonstrating all Underdark CSS layouts can be used to check if all Underdark CSS layout styles are okay. See The Underdark CSS base and layout styles are loaded.
Test pages containing styled Underdark CSS modules can be found at The Underdark CSS base, layout and module styles are loaded.


Modules are developed mostly independent of style. Only some block style and state CSS are a part of the module itself. Only the Underdark CSS base and module styles are loaded. The base styles set a sane line height of 1.5. The module styles set the before mentioned module-specific styles. To see a module without any aditional Underdark CSS styles applied to it, check


If you encounter a bug in the framework you can check the following: Is it an unknown issue on our bugtracker? It the bug browser specific, maybe even browser version, or platform specific? Can you produce a minimal test page triggering the bug? If so, please commit the bug and its test page, including a description of the expected and current behaviour to us on the bugtracker.

Feature requests

Most of the time extra styles should be defined in theme.css. If certain styles should not be project-specific, but rather be global, a feature request can be done via our bugtracker. An example of this would be html5 standard elements that we have not styled to conform with the rest of the default theme yet. Or perhaps elements that should have an obvious style when inside a certain hierarchy.


Standardisation or increased consistency in naming.

The API endpoints should be as clean as possible. Since version 0.3 we no longer put a v in front of the version number in the URL.


Do you have any constructive ideas regarding any issue? We are happy to receive any feedback.

Further reading