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!
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:
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.
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.
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.
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 three folder locations: your markup folder, your scripts 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 contains Hydrogen's default settings and will be where you can customize Hydrogen's settings and theme.
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(purple)">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.
To begin, let's dissect how a Hydrogen attribute works so that we can better understand how to use them.
data-h2-PROPERTY="MEDIA:STATE(ARGUMENTS)"
Hydrogen attributes have 5 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.:STATE
: this optional value allows you to set Hydrogen styles for a particular state on a handful of Hydrogen properties. You can see a list of of available states and which properties they can be used with below.ARGUMENTS
: each property has its own special set of arguments, outlined in the documentation below, that will define how the element is styled.💡 Using Hydrogen with a JavaScript Library?
It's important that you use Hydrogen attributes in their entirety so that Hydrogen can properly understand which attributes it needs to include in your final CSS file. This means you need to avoid using variables or props inside of an attribute. Rather, it's recommended that you include the attribute itself as the variable or prop. We consider this a bug, and you can see discussion on it here.
var myAttribute = "data-h2-bg-color='b(red)'" ... div myAttribute
var myVar = "red" ... div data-h2-bg-color="b(myVar)"
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(purple) l(red)"
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.
The state property allows you to modify a media query so that its arguments only apply to a particular element's state. This is handy for manipulating styles on things like :hover
so that a link or button behaves a certain way when a user hovers over it with their cursor.
For example, if we wanted to change the color of a link from red to purple when it's hovered, we'd do the following:
<a href="" title="" data-h2-font-color="b(red) b:h(purple)">My link</a>
Hydrogen provides options for the following states:
:h
:a
:f
:d
Because states are intimately tied with the volume of CSS Hydrogen produces, it was important to thoughtfully limit their scope to properties that make sense, rather than allowing their use on every single Hydrogen property. This means that states can be used with the following:
bg-color border display font-color font-style font-weight margin overflow padding radius shadow visibility width
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 to add opacity variations for each. By default, Hydrogen won't generate any opacity variations, but you can add as many as you need for your project.
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 custom opacity values, and to do so, colors have some prefix and suffix syntax that can be optionally included in the config file:
[dark]COLOR
for light/dark versionsCOLOR[.6]
for referencing an opacityFor 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:
decimal (0.4, .67) percentage (20%)
These values can even be combined to target a transparent dark variation, for example: data-bg-color="b([dark]purple[.5])"
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 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.
npx h2-watch
will produce a production ready copy of Hydrogen based on your config and then begin to watch the folders that you've specified in your markup and styles options for changes. When these files change, Hydrogen will automatically rebuild itself with the new attributes you've added. This is probably the command you'll use most and is helpful if you're actively developing on your project. Hydrogen will also watch for changes to your configuration, and perform a more thorough rebuild to account for your new settings.
npx h2-build
is similar to watch
but will only run once. This is preferrable if you're preparing to deploy your project for production and will produce a CSS file containing only the styles you've used in your project. You can learn more about this in the "What is Hydrogen?" section.
npx h2-compile
will compile Hydrogen's library in its entirety based on your configuration and produces a very large file size. This command is helpful if you don't want to wait for automatic watching to compile for you but will result in longer page load times. This command shouldn't be used in production.
After running npx h2-init
, a hydrogen.config.json
file will be located in the root of your project. In this file, you can edit Hydrogen's defaults or specify a variety of options that will modify how Hydrogen works and the theme it applies to its stylesheet.
If you have run npx h2-init
these configuration lines are already set. These options indicate to Hydrogen where it should find your markup and scripts as well as where it should place its final CSS file.
"folders": { "markup": "path/to/markup/folder", "scripts": "path/to/scripts/folder", "styles": "path/to/css/folder" }
While by default the folders configuration contains only one option for markup and scripts, this configuration can also be set to an array if your project has multiple markup or script folders:
"folders": { "markup": [ "first/path/to/markup/folder", "second/path/to/markup/folder" ], "scripts": [ "first/path/to/scripts/folder", "second/path/to/scripts/folder" ], "styles": "path/to/css/folder" }
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": [ { "key": "s", "value": "48em" }, { "key": "m", "value": "64em" }, { "key": "l", "value": "100em" } ]
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,
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,
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": [ { "key": "s", "weight": "1px" }, { "key": "m", "weight": ".5rem" }, { "key": "l", "weight": "1rem" } ]
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 opacities
array can be passed either decimal values or percentages, which tells Hydrogen to build an opacity variant for that color, so that it can be referenced using the opacity suffixes. Below are the default values.
"colors": [ { "key": "white", "color": "rgba(255, 255, 255, 1)", "opacities": [ ".2" ] }, { "key": "black", "color": "rgba(20, 20, 30, 1)" }, { "key": "purple", "color": "#9D5CFF", "opacities": [ ".1" ] }, { "key": "blue", "color": "#5CFFEE" }, { "key": "pink", "color": "#FF5C6D" } ],
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": [ { "key": "s", "maxWidth": "39rem" }, { "key": "m", "maxWidth": "60rem" }, { "key": "l", "maxWidth": "80rem" } ]
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 },
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. Here's an example of what loading in Open Sans from Google Fonts looks like:
"fonts": [ { "key": "open", "loadType": "webfont", "value": "'Open Sans', sans-serif", "url": null } ]
Below are the default values.
"fonts": [ { "key": "sans", "loadType": "system", "value": "sans-serif", "url": null }, { "key": "serif", "loadType": "system", "value": "serif", "url": null },{ "key": "script", "loadType": "system", "value": "script", "url": null }, { "key": "mono", "loadType": "system", "value": "monospace", "url": null } ]
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%"
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"
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": [ { "key": "purple", "color": "#9D5CFF" }, { "key": "blue", "color": "#5CFFEE" }, { "key": "pink", "color": "#FF5C6D" } ] }, { "type": "linear", "angle": "135deg", "colorStops": [ { "key": "purple", "color": "#9D5CFF" }, { "key": "blue", "color": "#5CFFEE" } ] } ]
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": [ { "key": "s", "value": "10px" }, { "key": "m", "value": "50rem" },{ "key": "l", "value": "100%" } ]
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": [ { "key": "xs", "value": "0 0.1rem 0.2rem 0 rgba(0, 0, 0, .2)" }, { "key": "s", "value": "0 0.25rem 0.5rem -0.05rem rgba(0, 0, 0, .2)" }, { "key": "m", "value": "0 0.4rem 0.7rem -0.1rem rgba(0, 0, 0, .2)" }, { "key": "l", "value": "0 0.55rem 1rem -0.2rem rgba(0, 0, 0, .2)" }, { "key": "xl", "value": "0 0.7rem 1.5rem -0.3rem rgba(0, 0, 0, .2)" } ]
This setting allows you to control the exponential values of how whitespace is calculated.
"whitespaceScale": "1.5"
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:
Sets a border on the element.
Syntax:
data-h2-border="MEDIA(COLOR, SIDE, STYLE, WEIGHT)"
Default Arguments:
Examples:
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:
Sets the element's display value.
Syntax:
data-h2-display="MEDIA(DISPLAY)"
Default Arguments:
Sets the element's align-content value.
Syntax:
data-h2-align-content="MEDIA(ALIGNMENT)"
Default Arguments:
Sets the element's align-items value.
Syntax:
data-h2-align-items="MEDIA(ALIGNMENT)"
Default Arguments:
Sets the element's align-self value.
Syntax:
data-h2-align-self="MEDIA(ALIGNMENT)"
Default Arguments:
Sets the element's flex-direction value.
Syntax:
data-h2-flex-direction="MEDIA(DIRECTION)"
Default Arguments:
Sets the element's justify-content value.
Syntax:
data-h2-justify-content="MEDIA(JUSTIFICATION)"
Default Arguments:
Sets the element's flex-wrap value.
Syntax:
data-h2-flex-wrap="MEDIA(WRAP)"
Default Arguments:
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:
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:
Sets a color value on the element's text.
Syntax:
data-h2-font-color="MEDIA(COLOR)"
Default Arguments:
Sets a font family value on the element's text.
Syntax:
data-h2-font-family="MEDIA(FAMILY)"
Default Arguments:
Sets a font size value on the element's text.
Syntax:
data-h2-font-size="MEDIA(SIZE)"
Default Arguments:
Sets one of a few various style options on the element's text.
Syntax:
data-h2-font-style="MEDIA(STYLE)"
Default Arguments:
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:
Aligns the element's text.
Syntax:
data-h2-text-align="MEDIA(ALIGNMENT)"
Default Arguments:
Sets an element's top, right, bottom, and left values.
Syntax:
data-h2-location="MEDIA(SIDE, WHITESPACE)"
Default Arguments:
Examples:
Sets an element's position value.
Syntax:
data-h2-position="MEDIA(POSITION)"
Default Arguments:
Sets a margin value on the specified side(s) of the element.
Syntax:
data-h2-margin="MEDIA(SIDE, WHITESPACE)"
Default Arguments:
Sets a padding value on the specified side(s) of the element.
Syntax:
data-h2-padding="MEDIA(SIDE, WHITESPACE)"
Default Arguments:
Sets an overflow value on an element to hide or show its children.
Syntax:
data-h2-overflow="MEDIA(ORIENTATION, OVERFLOW)"
Default Arguments:
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:
Adds a drop shadow effect to the element.
Syntax:
data-h2-shadow="MEDIA(SHADOW)"
Default Arguments:
Examples:
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:
Sets a handful of CSS properties that affects the element's width.
Syntax:
data-h2-width="MEDIA(WIDTH)"
Configuring width will overwrite all default values except for auto
.
Default Arguments: