Hydrogen's current release.

Hydrogen

An open-source, utility-first styling tool.

💡 What is Hydrogen?

Hydrogen is a utility-first styling tool for creating web interfaces without writing CSS.

It leverages data-attributes to allow the styling of elements right in your markup, rather than creating your own classes. Hydrogen offers a comprehensive library of tools and configurations for easy, seamless development. When you're ready to publish your project, it then processes your markup and creates a custom CSS file that contains only the code you've used, reducing its own footprint.

<div 
  data-h2-bg-color="b(white)"
  data-h2-padding="b(top-bottom, m) m(all, l)"
  data-h2-radius="b(s)"
  data-h2-shadow="b(s) m(m)">
  <p 
    data-h2-text-align="b(center)">
    Welcome to <span data-h2-font-color="b(purple)">Hydrogen</span>!
  </p>
</div>

Welcome to Hydrogen!

Data Attributes?

Why use data-attributes over class?

There's been a lot of discussion around classes performing better than data attributes, and we took this into consideration when designing Hydrogen. A lot of traditional class practices like BEM are effective, but can result in some really complex, bloated class attributes, which can have impacts on our ability to consume and write code. One of Hydrogen's primary goals is to make the end-user experience AND the developer experience easier, and so we decided to use data attributes for a few reasons:

  • they provide consistent namespacing
  • they provide a context and a value
  • their values are flexible, and allow for modifiers
  • they allow for complex combinations
  • they're easy to manipulate with JavaScript

In combination with Hydrogen's ability to generate a custom CSS file that contains only what you've used, the performance trade-offs are worth the improved experience. It was of the utmost importance that Hydrogen considered maintenance and legibility so that markup could be easily understood while retaining good performance and a small footprint.

Customization?

Hydrogen offers customization of both style and syntax through a comprehensive JSON configuration file. Include as many media queries, colors, gradients, and more as your project needs to get the job done. The Configuration and Themes section of the documentation offers more detail about how this file works.

File Size?

When you're ready to publish your project to the world, Hydrogen's build script will process your HTML, React, etc. and find exactly the attributes your project is using. It then compiles a CSS file that is specifically designed for your project. No bloat, no unused classes or CSS. By doing so, Hydrogen's file size drops drastically, improving both page load speeds and the performance of the data-attributes themselves.

💬 How to Use Hydrogen

Installation

First, we'll need to install NPM if you don't already have it on your machine. From there, in a command prompt/terminal window, navigate to the root of your project and enter:

npm install @hydrogen-design-system/hydrogen.css --save-dev

After the installation completes, you can run:

npx h2-init

The above command will prompt you to enter two folder locations: your markup folder and your styles/CSS folder. Simply enter the path from the root of your project (e.g. src/my/markup). Once you've submitted these paths, Hydrogen will automagically create a hydrogen.config.json file in the root of your project. This file will be where you can customize Hydrogen's settings and theme.

Getting Started

In order to start using Hydrogen, you need to enable it on your project. After compiling Hydrogen, a complete CSS file will appear in your specified styles folder, so include this file in your page's head element.

<head>
  <link rel="stylesheet" href="path/to/hydrogen.css">
</head>
<body>
  <div data-h2-bg-color="b(black)">
    <span data-h2-font-color="b(theme-1)">My Hydrogen styles work here!</span>
  </div>
</body>

Hydrogen contains a handful of basic reset and typography CSS that might affect your existing styles. You can find out more about these styles below if you're trying to determine what might be altering your project's original CSS.

Syntax

To begin, let's dissect how a Hydrogen attribute works so that we can better understand how to use them.

data-h2-PROPERTY="MEDIA(ARGUMENTS)"

Hydrogen attributes have 4 distinct pieces to them:

  • data-h2-: this is how custom data-attributes are defined in HTML. The h2 bit ensures that Hydrogen's attributes are namespaced and won't interfere with other frameworks.
  • PROPERTY: the property portion is where we specify which CSS property we want to style. A list can be found starting with background color below.
  • MEDIA(): this is how we define at which media query we want our styles to apply at. You can learn more about how to use media queries and which ones are installed by default below.
  • ARGUMENTS: each property has its own special set of arguments, outlined in the documentation below, that will define how the element is styled.

Media Queries

Media queries in Hydrogen are designed to allow you to granularly control each property when you need it. Rather than being forced to write unique styles for a particular element, you can directly target that element's property at the exact query you need right in your markup.

Hydrogen comes with a default set of 4 media queries out of the box:

b
s (48em)
m (64em)
l (100em)

Using a media query is simple:

data-h2-bg-color="b(black) m(theme-1) l(theme-2)"

Renders something like this (try resizing your screen!):

If the built in media queries don't suit your needs, you can customize them in your hydrogen.config.json file.

Color and Gradients

Hydrogen comes with a set of 5 pre-installed colors, but we know that color is almost always something you're going to want to control. In this section, we want to explain how color is used in the context of property arguments, rather than highlight the colors themselves. You can customize the exact palette for your application by following the instructions in the Themes section.

black
white
purple
blue
pink

When colors are built in Hydrogen, a light and dark version of each colors is created, and there is the option for each one to enable automatic generation of opacity variations. Hydrogen's default colors have this opacity option disabled, but these can be extremely helpful if your application frequently uses variations in its UI.

The simplest way to reference a color in a property argument is to simply use its name: data-h2-bg-color="b(purple)". Sometimes however, we want to tap into the automatically created lighter, darker, or transparent versions of a color, and to so, colors have some prefix and suffix syntax that can be optionally included:

  • [dark]COLOR for light/dark versions
  • COLOR[.6] for referencing an opacity

For referencing light and dark variations of your color, you can use the following:

light
dark





For referencing opacity values when you've enabled them, you can use the following increments:

0
.1
.2
...
.8
.9
1

These values can even be combined to target a transparent dark variation, for example: data-bg-color="b([dark]purple[.5])"

Gradients

Hydrogen doesn't ship with any gradients enabled by default, but you can optionally configure them in the gradients section of your configuration file.

Gradients are supported by the following properties:

bg-color

When they are enabled, you can reference them in place of a color value by using the following syntax: TYPE-ANGLE[COLORSTOP1][COLORSTOP2].

More specifically, radial gradients will not accept an angle value, while linear gradients require them. These angle values are assigned in your configuration file.

Examples:

linear-45[purple][blue]
radial[pink][purple]
linear-270[purple][blue][pink]

Whitespace

Whitespace in Hydrogen works within certain constraints. In order to help ensure the flow of whitespace is consistent in your app and you aren't worrying about arbitrary values for margins, padding, and the like, Hydrogen generates a set of whitespace values for you using the whitespaceScale option in your configuration file.

By default, the whitespaceScale value is set to 1.5, and this means that, starting with 1rem, whitespace values are calculated like this:

none (0rem)
xxs (0.4444rem)
xs (0.6666rem)
s (1rem)
m (1.5rem)
l (2.25rem)
xl (3.375rem)
xxl (5.0625rem)

These values can be used in any property that has a WHITESPACE argument.

📃 Commands

Compile

npx h2-compile will tell Hydrogen to compile its whole CSS file once, based on your current configuration. This will output Hydrogen in its entirety, so you'll be able to add and remove markup with little friction or waiting for a compile to finish.This is probably the command you'll use most and is helpful if you're actively developing on your project.

Build

npx h2-build should be used when you're ready to deploy your project, as it will compile Hydrogen by searching through your markup and create a CSS file that contains only the parts of Hydrogen that you've used, rather than the whole system, thus reducing Hydrogen's file size drastically. You can learn more about this in the "What is Hydrogen?" section.

🔨 Configuration and Themes

After running npx h2-init, a hydrogen.config.json file will be located in the root of your project. In this file, you can specify a variety of options that will modify how Hydrogen works and the theme it applies to its stylesheet.

Functional Configuration

Setting Up Project Folders

If you have run npx h2-init these configuration lines are probably already set. These options indicate to Hydrogen where it should find your markup and where it should spit out its final CSS file.

"folders": {
  "markup": "path/to/markup/folder",
  "styles": "path/to/css/folder"
}

While by default the folders configuration contains only one option for markup, this configuration can also be set to an array if your project has multiple markup locations:

"folders": {
  "markup": [
    "first/path/to/markup/folder",
    "second/path/to/markup/folder"
  ],
  "styles": "path/to/css/folder"
}

Choosing Media Queries

By default, Hydrogen comes with 4 default media queries, one of which (b for "base") will always be available on your project. You can configure your own media queries by modifying the list below in your configuration file to suit your project's needs. If you're happy with the default options, you can omit this from your configuration file.

"media": [
  {
    "name": "s",
    "value": "48em"
  },
  {
    "name": "m",
    "value": "64em"
  },
  {
    "name": "l",
    "value": "100em"
  }
]

Media Query Warnings

This option is set to false by default. Setting this to true will allow warning messages to appear in your console during a production build to indicate if there are media queries being used in your markup that aren't included in the media configuration outlined above. These messages can be helpful to find typos or queries that simply don't exist.

"mediaWarnings": true,

Debug Settings

This option is set to false by default. Setting this to true will prevent Hydrogen from cleaning up its cache (found in your CSS folder). This can be helpful to inspect the various output files during Hydrogen's build to locate problems or bugs.

"debug": true,

Theme Settings

Border Settings

This setting allows you to create custom, named border weights. The name value will be how you reference border weight in your attribute arguments, while the weight value will be the corresponding value in CSS. Below are the default settings.

"borderWeights": [
  {
    "name": "s",
    "weight": "1px"
  },
  {
    "name": "m",
    "weight": ".5rem"
  },
  {
    "name": "l",
    "weight": "1rem"
  }
]

Colors

This setting allows you to theme Hydrogen's colors. The name value will be how you reference color in your attribute arguments, the color value will be the corresponding value in CSS and can accept RGB, RGBA, and HEX values, and finally, the opacity value can be set to true or false, which tells Hydrogen to build an opacity map for that color, so that it can be referenced using the opacity suffixes. Below are the default values.

"colors": [
  {
    "name": "white",
    "color": "rgba(255, 255, 255, 1)",
    "opacity": false
  },
  {
    "name": "black",
    "color": "rgba(20, 20, 30, 1)",
    "opacity": false
  },
  {
    "name": "purple",
    "color": "#9D5CFF",
    "opacity": false
  },
  {
    "name": "blue",
    "color": "#5CFFEE",
    "opacity": false
  },
  {
    "name": "pink",
    "color": "#FF5C6D",
    "opacity": false
  }
]

Containers

This setting allows you to create custom container widths. The name value will be how you reference widths in your attribute arguments, while the maxWidth value will be the container's maximum width. Hydrogen will automatically generate alignments for all of your containers. Below are the default values.

"containers": [
  {
    "name": "s",
    "maxWidth": "39rem"
  },
  {
    "name": "m",
    "maxWidth": "60rem"
  },
  {
    "name": "l",
    "maxWidth": "80rem"
  }
]

Flex Grid Settings

This setting allows you to enable the flex grid and set how many columns it should generate. Below are the default values.

"flexgrid": {
  "enabled": false,
  "columns": 12
},

Font Families

This setting allows you to create distinct, named font families. The name value will be how you reference the font family in your attribute arguments. The loadType value can be set to system, webfont, or font-face to tell Hydrogen how it should be loaded. The value option is the CSS you want to be used to display this font - don't forget to include a system fallback in this line! Finally, the url value will tell font-face style families where the font files should be loaded from. Below are the default values.

"fonts": [
  {
    "name": "sans",
    "loadType": "system",
    "value": "sans-serif",
    "url": null
  },
  {
    "name": "serif",
    "loadType": "system",
    "value": "serif",
    "url": null
  },{
    "name": "script",
    "loadType": "system",
    "value": "script",
    "url": null
  },
  {
    "name": "mono",
    "loadType": "system",
    "value": "monospace",
    "url": null
  }
]

Font Base Size

This option will set a font size value on your project's <html> element and determines the base size of type on your page. By default, browsers set the default font size (1rem) to 16px. By using a percentage value, you can choose to make this 16px lr (over 100%) or ser (under 100%). Below is the default value.

"fontBaseSize": "112.5%"

Font Scale

This option determines the exponential rate at which the typography sizes are generated. Heading sizes are determined by multiplying the font base size by this value on a scale. You can learn more about choosing a value for your font scale using this handy Type Scale tool.

"fontScale": "1.25"

Gradients

Hydrogen doesn't come with gradients enabled by default, but using this setting, you can create custom gradients and make them available for properties that accept them. Below are examples of both radial and linear gradients. The type value allows you to select the gradient type. The angle value is only applicable for linear gradients and determines that angle at which the gradient will travel. The colorStops array allows you to define as many color stops as you need, as well as their position. These gradient configurations will automatically generate a gradient option following the syntax outlined in the color section.

"gradients": [
  {
    "type": "radial",
    "colorStops": [
      {
        "name": "purple",
        "color": "#9D5CFF"
      },
      {
        "name": "blue",
        "color": "#5CFFEE"
      },
      {
        "name": "pink",
        "color": "#FF5C6D"
      }
    ]
  },
  {
    "type": "linear",
    "angle": "135deg",
    "colorStops": [
      {
        "name": "purple",
        "color": "#9D5CFF"
      },
      {
        "name": "blue",
        "color": "#5CFFEE"
      }
    ]
  }
]

Radius

This option allows you to set custom radius values. The name will be how you reference the radius in your attribute arguments. The value option is the radius CSS value you want. Below are the default options.

"radius": [
  {
    "name": "s",
    "value": "10px"
  },
  {
    "name": "m",
    "value": "50rem"
  },{
    "name": "l",
    "value": "100%"
  }
]

Shadows

This setting allows you to create custom shadow values. The name will be how you reference the shadow in your attribute arguments. The value option is the box-shadow CSS you want your shadow to use. Below are the default options.

"shadows": [
  {
    "name": "xs",
    "value": "0 0.1rem 0.2rem 0 rgba(0, 0, 0, .2)"
  },
  {
    "name": "s",
    "value": "0 0.25rem 0.5rem -0.05rem rgba(0, 0, 0, .2)"
  },
  {
    "name": "m",
    "value": "0 0.4rem 0.7rem -0.1rem rgba(0, 0, 0, .2)"
  },
  {
    "name": "l",
    "value": "0 0.55rem 1rem -0.2rem rgba(0, 0, 0, .2)"
  },
  {
    "name": "xl",
    "value": "0 0.7rem 1.5rem -0.3rem rgba(0, 0, 0, .2)"
  }
]

Whitespace Scale

This setting allows you to control the exponential values of how whitespace is calculated.

"whitespaceScale": "1.5"

🎨 Style Attributes

Background Colors

Sets a color or gradient as the element's background color value.

Syntax:

data-h2-bg-color="MEDIA(COLOR)"
data-h2-bg-color="MEDIA(GRADIENT)"

Default Arguments:

Examples:

Borders

Sets a border on the element.

Syntax:

data-h2-border="MEDIA(COLOR, SIDE, STYLE, WEIGHT)"

Default Arguments:

Examples:

Containers

Adds fixed margins to the element so that its content is contained within the space. No container will exceed more than 90% of the viewport.

Syntax:

data-h2-container="MEDIA(ALIGNMENT, SIZE)"

Default Arguments:

Examples:

Display

Sets the element's display value.

Syntax:

data-h2-display="MEDIA(DISPLAY)"

Default Arguments:

Flex Grid

Flex Grids

Flexbox grids are disabled by default, but can be enabled in your Hydrogen configuration file. Flexbox grids are generated by specifying a couple options on the wrapper (data-h2-flex-grid) and then defining how each child should be distributed within the column setup.

Syntax:

data-h2-flex-grid="MEDIA(ALIGNMENT, EXPANSION, GRID-PADDING, GUTTER)"

Default Arguments:

Examples:

Flex Items

By default H2 offers a 12 column grid, meaning you can specify flex items using a range of 1 to 12.
e.g. data-h2-flex-item="b(1of1) s(1of2) m(1of6) l(1of12)"
These values are calculated as percentages, so 1of2 meaning that the item will span 1 of the columns if the grid were 2 columns wide (meaning this item would span 50% of the available space). Similarly, 1of3 would span 33% of the grid, while 2of5 would span 40% of the grid.

Syntax:

data-h2-flex-item="MEDIA(XofY)"

Default Arguments:

Flex Properties

Align Content

Sets the element's align-content value.

Syntax:

data-h2-align-content="MEDIA(ALIGNMENT)"

Default Arguments:

Align Items

Sets the element's align-items value.

Syntax:

data-h2-align-items="MEDIA(ALIGNMENT)"

Default Arguments:

Align Self

Sets the element's align-self value.

Syntax:

data-h2-align-self="MEDIA(ALIGNMENT)"

Default Arguments:

Flex Direction

Sets the element's flex-direction value.

Syntax:

data-h2-flex-direction="MEDIA(DIRECTION)"

Default Arguments:

Justify Content

Sets the element's justify-content value.

Syntax:

data-h2-justify-content="MEDIA(JUSTIFICATION)"

Default Arguments:

Flex Wrap

Sets the element's flex-wrap value.

Syntax:

data-h2-flex-wrap="MEDIA(WRAP)"

Default Arguments:

Font Properties

Font Color

Sets a color value on the element's text.

Syntax:

data-h2-font-color="MEDIA(COLOR)"

Default Arguments:

Font Families

Sets a font family value on the element's text.

Syntax:

data-h2-font-family="MEDIA(FAMILY)"

Default Arguments:

Font Size

Sets a font size value on the element's text.

Syntax:

data-h2-font-size="MEDIA(SIZE)"

Default Arguments:

Font Style

Sets one of a few various style options on the element's text.

Syntax:

data-h2-font-style="MEDIA(STYLE)"

Default Arguments:

Font Weight

Sets a numeric font weight on the element's text.

Syntax:

data-h2-font-weight="MEDIA(WEIGHT)"

Please note that font weight availability will depend on the font family you're using on your project. If the font doesn't support certain weights, the value will not work as expected.

Default Arguments:

Text Align

Aligns the element's text.

Syntax:

data-h2-text-align="MEDIA(ALIGNMENT)"

Default Arguments:

Overflow

Sets an overflow value on an element to hide or show its children.

Syntax:

data-h2-overflow="MEDIA(ORIENTATION, OVERFLOW)"

Default Arguments:

Positioning

Location

Sets an element's top, right, bottom, and left values.

Syntax:

data-h2-location="MEDIA(SIDE, WHITESPACE)"

Default Arguments:

Examples:

Position

Sets an element's position value.

Syntax:

data-h2-position="MEDIA(POSITION)"

Default Arguments:

Radius

Sets the element's corner radius values.

Syntax:

data-h2-radius="MEDIA(RADIUS)"
data-h2-radius="MEDIA(RADIUS, RADIUS, RADIUS, RADIUS)"

When assigning different values to each corner, the order is top-left, top-right, bottom-right, bottom-left.

Default Arguments:

Examples:

Shadows

Adds a drop shadow effect to the element.

Syntax:

data-h2-shadow="MEDIA(SHADOW)"

Default Arguments:

Examples:

Visibility

Sets a handful of CSS properties that affects the element's visibility to users and machines.

Syntax:

data-h2-visibility="MEDIA(VISIBILITY)"

Note that invisible hides the element visually, but it will still be found by assistive technologies. To hide the element entirely, use hidden.

Default Arguments:

Whitespace

Margins

Sets a margin value on the specified side(s) of the element.

Syntax:

data-h2-margin="MEDIA(SIDE, WHITESPACE)"

Default Arguments:

Padding

Sets a padding value on the specified side(s) of the element.

Syntax:

data-h2-padding="MEDIA(SIDE, WHITESPACE)"

Default Arguments: