Tutorial: How to create a grid with flexbox in React

Serhii Shramko

Serhii Shramko /

3 min read--- views

Don't forget to specify alt

Often in the life of a web developer, you need to make a grid, but the limitations of the browser (Internet Explorer 😭) do not allow you to use, for example, CSS Grid.

This is where CSS Flexbox comes to the rescue. He is our friend, brother and helper. 🫡

This post is about how to create a flexbox-based grid component in React. The component should be reusable and painless to configure.

Preparation

Many of those who created components in React are familiar with the classnames library, but I want to recommend you the clsx library, which is smaller and similar in functionality.

It is not necessary for our component, but it is more comfortable with them:

npm i clsx

Step 1: Create React component architecture

const Grid = ({ children }) => (
  <div className='grid'>
    {children}
  </div>
);
const GridColumn = ({ children }) => (
  <div className='grid__col'>
    {children}
  </div>
);
const GridRow = ({ children }) => (
  <div className='grid__row'>
    {children}
  </div>
);

Step 2: Create styles with SCSS

I use the BEM methodology for styles, as I think it is excellent for component libraries.

// Base styles
.grid {
  width: 100%;

  &__row {
    display: flex;
    flex-wrap: wrap;
  }

  &__col {
    flex-grow: 1;
    flex-shrink: 0;

    // For decoration only
    background-color: #bbeffd;
    border: 1px solid #61dafb;
    padding: 15px;
    text-align: center;
    margin-bottom: 25px;
  }
}

What about columns logic?

.grid__row--col-3 > .grid__col {
  width: 33%;
}

.grid__row--col-2 > .grid__col {
  width: 50%;
}

It is so ugly. Why we need to do it manually?

Let's try some Sass magic 🪄?

$columnsNumberToWidth: (
  2: 50%,
  3: 33%,
  4: 25%,
  5: 20%,
  6: 16.6%,
);

@each $number, $width in $columnsNumberToWidth {
  .grid__row--col-#{$number} > .grid__col {
    width: $width;
  }
}

You can see how SASS code is transformed into CSS here:

sassmeister site screenshot

Step 3: Add logic to the GridRow component.

import clsx from 'clsx';

const GridRow = (pops) => {
  const {
    children,
    columns,
  } = props;

  const rootClasses = clsx('grid__row', {
    [`grid__row--col-${columns}`]: columns,
  });

  return (
    <div className={rootClasses}>
      {children}
    </div>
  );
};

Let's check result

<Grid>
  <GridRow columns={6}>
    <GridColumn>1 of 6</GridColumn>
    <GridColumn>2 of 6</GridColumn>
    <GridColumn>3 of 6</GridColumn>
  </GridRow>

  <GridRow columns={6}>
    <GridColumn>1 of 6</GridColumn>
    <GridColumn>2 of 6</GridColumn>
    <GridColumn>3 of 6</GridColumn>
    <GridColumn>4 of 6</GridColumn>
    <GridColumn>5 of 6</GridColumn>
    <GridColumn>6 of 6</GridColumn>
  </GridRow>

  {/* ...  */}
</Grid>
First example grid screenshot

Recap

Writing components has an endless process ♾.

Next, you can add a dynamic size of each column, column gaps, change the component tag type, breakpoints and so on...

Therefore, below I share additional materials that may be useful:

Share it: