Introducing React iotaCSS

Dimitris Psaropoulos
iotaCSS
Published in
7 min readJun 21, 2017

In the past few years there have been a lot of conversations about React and CSS. New tools and best practices are seeing the light of the day each week and I feel the need to present my own.

As a Front-end Architect focused on building maintainable and scalable design systems for companies around the globe, I see myself in the middle of those two worlds. I am working with React for the last 3 and a half years and is one of the fundamentals of a great Design System. At the same time, be able to deeply understand CSS and express a UI on it, is a crucial part of the process and this is what I am trying to present. A way of thinking a UI in CSS and React.

I had the privilege to work with great designers and React engineers in the past few years and I wanted to create something that will be easy for designers to understand and at the same time to feel native to React engineers.

Presenting iotaCSS for React

React iotaCSS is a set of Stateless React Components which represent the iotaCSS Objects ( Grid, List, Media, Type, Container ). They have two main jobs, to translate the available CSS classes of each Object to React properties, for example:

<List align="middle" type="block">
<List.Item>
Item 1
</List.Item>
</List>

will generate:

<ul class="o-list o-list--middle o-list--block">
<li class="o-list__item">
Item 1
</li>
</ul>

and to translate the u prefixed properties to iotaCSS utility classes, for example:

<H1 uText="center">Hello World</H1>

will generate:

<h1 class="u-text-center">Hello World</h1>

That makes it natural to React engineers because we all know their love to CSS :P.

It comes with no CSS

Yes, you read correctly. React iotaCSS doesn’t load the iotaCSS for you. It lets you decide how to load and structure it yourself. That has a lot of benefits:

  1. You install iotaCSS the way you prefer
  2. You structure the iotaCSS folders / files the way you prefer
  3. You can still use iotaPlate, iotaCSS’s official CLI
  4. You can use create-react-app
  5. You can use any module bundler you prefer, Webpack, Browserify etc
  6. You can use any tool you like, CSS Modules, CSS-in-JS etc…

React iotaCSS role in a Design System

Enough with the theory, let’s move on to some more practical examples. Let’s take as an example this interface:

We’ll start by abstracting the pieces of our layout. We have:

  1. 3 typography sizes
  2. 2 margin sizes
  3. 1 padding size
  4. 1 font weights, bold ( well, and normal but it’s default )
  5. 2 colors ( black, grey )
  6. 1 background color ( white )
  7. 1 media object layout
  8. 1 React Component ( Post Component )

Creating our Design System with iotaCSS

Let’s start by defining our settings, starting with the colors:

// settings/colors.scss
// Variables to be used by all components
$color-black : '#0D2A4A';
$color-grey : '#7A8599';
$color-white : '#FFFFFF';
// A map for the shared color and background color
// utility options
$colors: (
black : $color-black,
grey : $color-grey,
white : $color-white
);

Then, we define our spacing sizes:

// settings/_spacing.scss$spacing-default: 7px;$spacing-x2 : $spacing-default * 2;
$spacing-x3 : $spacing-default * 3;
$spacing-extra: (
-x2 : $spacing-x2,
-x3 : $spacing-x3
);

Then, we define our typography sizes:

// settings/_type.scss// First param is the font-size, second is the line-height
$type-16: ( 16px, 21px );
$type-20: ( 18px, 21px );
$type-25: ( 25px, 28px );

Ok, now that we have all the settings in place, let’s proceed to utilities configuration, staring with Color and Background Color ones:

// utilities/_color.scss$iota-utils-color-names: $colors;@import 'node_modules/iotacss/utilities/color';
// utilities/_bgcolor.scss
$iota-utils-bgcolor-names: $colors;@import 'node_modules/iotacss/utilities/bgcolor';

continue with Margin and Padding:

// utilities/_margin.scss$iota-utils-margin-default: $spacing-default;
$iota-utils-margin-extra : $spacing-extra;
@import 'node_modules/iotacss/utilities/margin';
// utilities/_padding.scss
$iota-utils-padding-default: $spacing-default;
$iota-utils-padding-extra : $spacing-extra;
@import 'node_modules/iotacss/utilities/padding';

and finally configure the Weight utility:

// utilities/_weight.scss$iota-utils-weight-sizes: (
bold : 700
);

Now, let’s configure our two objects, Type and Media:

// objects/_type.scss$iota-objs-type-sizes: (
16: $type-16,
18: $type-18,
25: $type-25
);
@import 'node_modules/iotacss/objects/type';
// objects/_media.scss
$iota-objs-media-gutter-default: $spacing-default;
$iota-objs-media-aligned : true;
@import 'node_modules/iotacss/objects/media';

Great, now that all our CSS is in place it’s time to build our Post React Component and see the React iotaCSS in action. Let’s start by defining the available properties of the component:

import React from 'react'
import PropTypes from 'prop-types'
import classnames from 'classnames'
// Just some extra CSS for the Component itself since we
// cannot apply those styles using iotaCSS
import './Post.scss'
import {
Base,
H1 H2, P,
Media
} from 'react-iotacss'
const Post = ({
className,
children,
title,
authorAvatar,
authorName,
authorTitle
}) => {
// Component JSX here};Post.propTypes = {
className : PropTypes.string,
children : PropTypes.node,
title : PropTypes.string.isRequired,
authorAvatar : PropTypes.string.isRequired,
authorName : PropTypes.string.isRequired,
authorTitle : PropTypes.string.isRequired
}

Now, let’s start building the JSX part of the component:

const classes = classnames('c-post', className);return (

<Base className={classes} uP="x2" uBgcolor="white" ...props>

<H1 size="25" uWeight="bold" uMb>{title}</H1>
<P size="18" color="grey">{children}</P>
<Media align="middle">
<Media.Fixed>
<Avatar src={authorAvatar} />
</Media.Fixed>
<Media.Fluid>
<H2 size="16" uWeight="bold">{authorName}</H2>
<P size="16" color="grey">{authorTitle}</P>
</Media.Fluid>
</Media>
</Base>)

and before we finish, let’s create the Post.scss file and add some missing css for the component to complete:

// components/Post.scss$post-radius     : 4px;
$post-box-shadow : 0 1px 3px 0 rgba(28,45,157,0.28);
.c-post {
border-radius: $post-radius;
box-shadow: $post-box-shadow;
}

Ok, so, let’s explain what we did here:

  1. We used the Base Component from React iotaCSS. This component is extended by all other React iotaCSS components and only thing it does is it allows you to use the ‘u’ prefixed properties and it translates them into utility CSS classes. For example the uWeight="bold" translates to .u-weight-bold. The reason I used it as a wrapper on my Post Component is because I want this component also to accept utility properties when used.
  2. We used the H1, H2 and P components to apply our typography. All those components extend the Type component and they just apply the relative tagName. They don’t apply any typography size. You define the size using the size property.
  3. We used the Media Component to apply the media object style layout we see in the design.
  4. Finally, we imported an SCSS file relative to our component to apply the missing styles that iotaCSS don’t handle.

Benefits of this approach

There are a lot of benefits comes with this approach worth to mention. The most important of those are:

  1. You load only what you use. iotaCSS is a set of individual, small modules that are configured 100% to your needs. It will never generate any extra CSS you don’t need. That makes your UIs extremely light.
  2. You keep all your Design System’s configuration in one place, in the SCSS. That way, it protects you from developers applying any styling that doesn’t belong to the actual system. In case a new size or color needed, it has to be added to the design system first and then used.
  3. You reuse everything again and again. iotaCSS abstracting all little pieces every UI has and uses an elegant way so, you can always use them and avoid writing duplicated CSS. It allows you also to configure them to your needs. That increases performance and makes building new features light fast.
  4. As far as the available options are documented, ( for example, available typography sizes, colors etc ) the developer never needs to look into CSS again. He just needs to know what are the available options for each property.
  5. No need to scope your CSS. When your CSS is beautifully abstracted and architectured by iotaCSS, you don’t need to scope styles cause they don’t conflict anyways. Scoping your CSS is like disabling your warnings. You still have issues, you just don’t see them.

Demo

Explaining things step by step helps a lot understanding the process but nothing is compared to a real life demo application.

It doesn’t use any state management, it’s just a set of stateless components but it’s able to demonstrate well the structure of a complete application written in React iotaCSS.

iotaCSS Slack Community

I believe in instant communication more than anything so I decided to create an iotaCSS community on Slack.

This is the place where you can get helped, help others or propose and discuss new updates and features that you believe are useful for the framework. Also you can be the first to know when I start building something new and give feedback or be a part of it. Sign up at slack.iotacss.com. See you there!!

As always, special thanks to my friend Andrew Ckor for the illustrations of this post and to Marek Šuščák for a comprehensive review of the article.

Dimitris Psaropoulos is a front-end architect and performance engineer based in Prague, CZ. He had the privilege of working in products for companies such as Nike, Salesforce, Chipotle, Node.io, VanityFair & more. He is the creator of the iotaCSS Framework. Previously Lead Front-end Architect at Chute (YC12).

--

--

Dimitris Psaropoulos
iotaCSS

Co-Founder & CTO at TryAdvocate.com. Previously Design Systems Architect at Shopify.