Atomic

Using Atomic

Getting started building UIs.

Atomic CSS leans on small, tersely named, single-purpose classes that are combined in the HTML to build up UIs. This approach can speed development time, reduce complexity, and increase consistency by limiting, and in some cases eliminating, the need to author new CSS.

Getting Started

If you’re unfamiliar with Atomic CSS here are a few resources.

Syntax

The list of classes in Thumbprint Atomic are based primarily on Tachyons, easily the most popular of the Atomic libraries, with some syntax changes.

Scale

Classes that have no space between the letters and numbers reference a scale that grows exponentially. Our spacing units go from 4px, 8px, 16px and so on and is used by the margin and padding classes. Note that different concepts use different scales.

  • The class pa4 sets padding on all sides of an element using the fourth value in the spacing scale, which is 24px.
  • The class w1 sets the width of an element using the first value in the width scale, which is 16px.

Literal

Classes where a dash separates the letter and number reference literal values.

  • The class bw-2 sets the width of a border to 2px.
  • The class top-4 sets the value of the top property to 4px.

Responsive

Nearly all classes have variations that will apply styling at breakpoints. These classes are prefixed with s_, m_, and l_. In the this example a different padding-bottom value is applied at each breakpoint.

<div class="pb2 s_pb3 m_pb4 l_pb5"></div>
  • By default pb2.
  • Above the small breakpoint pb3.
  • Above the medium breakpoint pb4.
  • Above the large breakpoint pb5.

!important

For backwards compatibility with previous utility classes and to ensure that the Atomic class takes precedence in the CSS, every declaration includes the !important rule.

Usage

Thumbprint Atomic classes are available to all React and Twig pages on thumbtack.com.

React

Atomic is included in Layout.jsx which means all React pages will include Atomic classes by default. The recommended usage is to contain the classes in the JSX by using the Atomic classes directly, or as variables, and write any custom CSS not covered by Atomic classes in a Sass file.

CSS Modules

Do not add Atomic classes using the composes functionality that’s available in CSS Modules. Due to the specificity and the built-in responsiveness of Atomic classes, unexpected behavior can result.

JSX

<div className={`${styles.card} pb6 pt7 bg-gray-200 l_pt3`}></div>

Sass

This CSS is not included in our current Atomic library. Custom Sass must be written.

.card {
box-shadow: 0 0 2px 3px rgba(0, 0, 0, 0.2);
@include tp-respond-above($tp-breakpoint__large) {
min-height: 300px;
}
}

Legacy (Twig/Angular)

Atomic is included on every page using the legacy-angular-global-harness. Classes should be used in the HTML similar to the approach above: use Atomic classes wherever possible and add a custom class when needed.

HTML

<div class="card pb6 pt7 bg-gray-200 l_pt3"></div>

Sass

As with the previous Sass example above, since this CSS is not included in our current Atomic library, custom Sass must be written.

.card {
box-shadow: 0 0 2px 3px rgba(0, 0, 0, 0.2);
@include tp-respond-above($tp-breakpoint__large) {
min-height: 300px;
}
}

Adding new Atomic classes

We occasionally get requests to add new classes to the Atomic library. In an effort to balance the library’s completeness with its bundle size, we’ve adopted the approach that there should be at least 10 instances of a property in Thumbtack's website codebase before we add it to Atomic.

If the Atomic class you’d like is not available please write the custom CSS in your Sass file as shown the usage examples above. You can can also open an issue if you would like us to consider adding it.

Limitations

Although Atomic can significantly reduce the amount of CSS you write it won’t cover every use case. At times you’ll have to use other approaches.

  • Custom values Layouts will sometimes require non-standardized positioning, heights, or widths that aren’t available in the Atomic library. Hardcode them into your CSS with a comment.
  • last-child and first-child selectors Atomic isn’t well-suited to handle pseudo classes. For example, if you need margin-bottom on all objects but the last one, either:
    1. Use conditional logic in your loop to apply an Atomic margin-bottom class to all but the last item.
    2. Use a custom class and manage the margin in the CSS. You can also use the :not() selector for a one-liner that skips the last-child:
    .item:not(:last-child) {
    margin-bottom: $tp-space__3;
    }

Refactoring React

  • As a rule of thumb, if more than 50% of a React component is being updated the developer should convert the Sass styles to Atomic classes.
  • When adding Atomic to elements in legacy components, you do not need to convert the entire component, but at minimum convert all the CSS on the element you are updating. CRs should be blocked if this step has not been taken (within reason).
  • Similar to our migration from Twig to React, refactoring existing React pages to use Atomic will require the judgment of the developer.