Tachyons + Styled Components = Pure Joy
Tags: css, javascript, react, webdev
Published: 2023-08-25 06:30:00

This is a blog that I wrote 6 years ago, but just posting here to checkout Dev.to! I now moved to Tailwind but I thought this might be an interesting read for anyone interested to know how utility first systems first started.

I have been working on a chat bot authoring app for sometime now. Its now close to release & I found a methodology we experimented for styling to be a really big win.

I stumbled on the amazing functional CSS library — [Tachyons](http://www.tachyons.io/) a few months back. I was impressed by its philosophy right away, though I was quite skeptical about using it. After some experiments I took a chance & tried it on the project I was working on. It was not very smooth on day one but I picked up the library surprisingly fast! Before I knew it, I was writing Tachyons without needing the docs at all! The amount of CSS I wrote dropped so dramatically & the components started to look more consistent. It truly changed the way I did styling! It was so good that I refactored almost all of my side projects from scratch within no time, despite the time crunches!

> The amount of CSS I wrote dropped so dramatically & the components started to look more consistent.

Tachyons is *not* a full UI framework, its a set of utility classes that *does one thing, and does it well* — the Unix *philosophy*. It was so effective that the iteration speed & maintainability of the codebase jumped by an order of magnitude!

![Component from official docs](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xq3a757pedtnr90s5ehn.png)

``` html
<article class="mw5 center bg-white br3 pa3 pa4-ns mv3 ba b--black-10">
  <div class="tc">
    <img src="http://tachyons.io/img/avatar_1.jpg" class="br-100 h3 w3 dib" title="Photo of a kitty staring at you">
    <h1 class="f4">Mimi Whitehouse</h1>
    <hr class="mw3 bb bw1 b--black-10">
  </div>
  <p class="lh-copy measure center f6 black-70">
    Quite affectionate and outgoing.
    She loves to get chin scratches and will
    roll around on the floor waiting for you give her more of them.
  </p>
</article>
```
I started reading about it & watching all videos I could find. But I kept seeing one issue as a con. It made the markup very ugly. I do agree to that. My backend team members who tried to change few bits of frontend code got a headache. It was bad. Seriously bad.

``` js
import React from "react"
export function User({ name, username, imageURL }) {
  return (
    <main className="center w-50 sans-serif">
      <article className="w-100 bb b--black-05 pb2 mt2 flex items-center justify-between">
        <div className="flex items-center">
          <img
            src={imageURL}
            className="ba b--black-10 db br-100 w2 w3-ns h2 h3-ns mr2"
          />
          <div className="">
            <h1 className="f6 f5-ns fw6 lh-title black mv0">{name}</h1>
            <h2 className="f6 fw4 mt0 mb0 black-60">{username}</h2>
          </div>
        </div>
        <form>
          <button
            className="f6 button-reset bg-white ba b--black-10 dim pointer pv1 black-60"
            type="submit"
          >
            + Follow
          </button>
        </form>
      </article>
    </main>
  )
}
User.defaultProps = {
  name: "Alena Sanders",
  username: "@alenasanders",
  imageURL: "https://randomuser.me/api/portraits/women/57.jpg",
}
```

> Yup, its too dirty!

There was also another problem, a lot of my components happened to duplicate long set of class names! It was okay in the beginning but for a new developer looking at the codebase, it would be the most off putting sights.

I tried a few ways to reduce the duplication, but most were too cumbersome that I gave up on those efforts. Initially, I accepted the ugly markup as a trade off to accept for the advantages. But soon, I found a solution with an update to [Styled Components](https://www.styled-components.com/)!

> And suddenly there was an elegant solution to both these issues!!

They introduced a function to accept attributes — *attrs*. And suddenly there was an elegant solution to both these issues!! attrs enabled providing attributes like className while creating Styled Components. This not only made the markup clean but also enabled sharing the components for reuse. This was a huge win! I moved every other components to Styled Components & now my backend team who may just want to change something small in the frontend won’t be having a headache! In fact they love how good the markup looks now!

``` js
import React from "react"
import styled from "styled-components"
/*
  Move the SCs defined at the bottom outside if it gets too cluttered & import them as follows:
import {
    Main,
    Article,
    Image,
    Title,
    SubTitle,
    Button
  } from './StyledComponents'
*/
export function User({ name, username, imageURL }) {
  return (
    <Main>
      <Article>
        <div className="flex items-center">
          <Image src={imageURL} />
          <div>
            <Title>{name}</Title>
            <SubTitle>{username}</SubTitle>
          </div>
        </div>
        <form>
          <Button>+ Follow</Button>
        </form>
      </Article>
    </Main>
  )
}
User.defaultProps = {
  name: "Alena Sanders",
  username: "@alenasanders",
  imageURL: "https://randomuser.me/api/portraits/women/57.jpg",
}
const Main = styled.main.attrs({
  className: "center w-50 sans-serif",
})``
const Article = styled.article.attrs({
  className: "w-100 bb b--black-05 pb2 mt2 flex items-center justify-between",
})``
const Image = styled.img.attrs({
  className: "ba b--black-10 db br-100 w2 w3-ns h2 h3-ns mr2",
})``
const Title = styled.h1.attrs({
  className: "f6 f5-ns fw6 lh-title black mv0",
})``
const SubTitle = styled.h2.attrs({
  className: "f6 fw4 mt0 mb0 black-60",
})``
const Button = styled.button.attrs({
  className: "f6 button-reset bg-white ba b--black-10 dim pointer pv1 black-60",
  type: "submit",
})``
```

If you haven’t yet tried it, consider it. Styled Components & Tachyons are a match made in heaven :)