https://github.com/ppiyush13/react-styled-flex
Simple, light, unopinionated, css standard compliant Flexbox component for React using Styled Components
https://github.com/ppiyush13/react-styled-flex
flex flex-gap flexbox react react-flexbox styled styled-components
Last synced: about 1 year ago
JSON representation
Simple, light, unopinionated, css standard compliant Flexbox component for React using Styled Components
- Host: GitHub
- URL: https://github.com/ppiyush13/react-styled-flex
- Owner: ppiyush13
- License: mit
- Created: 2019-09-22T17:22:31.000Z (over 6 years ago)
- Default Branch: main
- Last Pushed: 2023-03-06T03:54:10.000Z (about 3 years ago)
- Last Synced: 2025-05-07T20:12:00.639Z (about 1 year ago)
- Topics: flex, flex-gap, flexbox, react, react-flexbox, styled, styled-components
- Language: TypeScript
- Homepage:
- Size: 5.2 MB
- Stars: 16
- Watchers: 2
- Forks: 1
- Open Issues: 15
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# react-styled-flex
[![module version and npm link][npm]][npm-url]
[![bundlephobia minified size][size-min]][bundlephobia-url]
[![bundlephobia minified + gzipped size][size-minzip]][bundlephobia-url]
[![types available][package-types]][npm-url]
[![Codacy Badge][codacy]][codacy-url]
[![CircleCI][build]][build-url]
[![codecov][coverage]][coverage-url]
Simple, light, unopinionated, CSS standard compliant Flexbox component for [react][react-git] using [styled-components][styled-components-git]
## š Changelog
This is `react-styled-flex@2` documentation. For version 1, please follow [this][version-1-docs] link. Following changes are introduced in v2:
### āļø Breaking changes
- `is` prop of FlexBox and FlexItem component is longer supported. Instead use native styled-components ["as" polymorphic prop][styled-components-as-prop] to render another react component or html element.
- Supports `styled-components` version greater than or equal to `>=5.1.0`. If you want to use older versions of `styled-components`, please install `react-styled-flex` v1 by using `npm install react-styled-flex@latest-1` command.
### š Enhancements
- Typescript rewrite.
- ~10% lightweight than v1.
- Supports SSR and SSG rendering.
- Introduces [Box](#Box) component.
- Uses `styled-components` [shouldForwardProp][styled-components-should-forward-prop] mechanism to avoid leaking props to DOM. As a result, `is` prop from v1 is no longer supported.
## š Features
- **Lightweight and dependency free**, ~2.7 KB minified or ~1.2 KB minified + gzipped.
- **Clean underlying HTML DOM**. No prop leakage to DOM.
- Supports [flex-gap][flex-gap] feature. For non supported browsers, it degrades gracefully by applying appropriate margin properties.
- [Supports rendering](#change-underlying-element) of any react component or html element.
- [Supports unitless values](#supports-unitless-values) wherever required.
- Supports SSR and SSG rendering.
- TypeScript support.
## šæ Installation
Yarn
```sh
yarn add react-styled-flex
```
Npm
```sh
npm i react-styled-flex
```
**react-styled-flex** requires peer dependencies [react][react-npm] and [styled-components][styled-components-npm]. You need to add them separately.
## š API
- **react-styled-flex** exports three components: `Box`, `FlexBox` and `FlexItem`.
- `Box` behaves as basic CSS box. `FlexBox` and `FlexItem` extends `Box`.
- `FlexBox` behaves as a container with `display: flex` rule.
- `FlexItem` as acts as a child for `FlexBox`. Though `FlexBox` can have other components as child as well.
- Only use `FlexItem` if you need to provide additional styles to child components. See [Props](#props) section for more details.
- `FlexItem` can be treated as `FlexBox` for nested children by setting `box` prop as `true` on `FlexItem`
## š¹ Usage
**react-styled-flex** exports three components: **Box**, **FlexBox** and **FlexItem**.
All renders simple div with styles derived from passed props.
```javascript
import { Box, FlexBox, FlexItem } from 'react-styled-flex';
const Layout = () => {
return (
Child 1
Child 2
Child 3
);
};
```
On rendering `Layout` component,
- One parent div with style `display: flex; justify-content: center; align-items: center` and three nested divs will be rendered.
- First child will have padding of `10px`.
- Second child will be simple div.
- Third child will have style `flex: 1;`
For rendering elements other than divs, please refer [Change underlying element
](#change-underlying-element) section.
## š Props
### Box
- All props are **optional**.
- Shorthand syntax for margin and padding props are supported.
| Props | Type | Description |
| ----------------- | :------------------------------: | ---------------------------------------------------------------------------- |
| sizing | _string_ | Applies [box-sizing][box-sizing-mdn] |
| position | _string_ | Applies [position][position-mdn] |
| height | _stringĀ |Ā number_ | Applies [height][height-mdn] |
| maxHeight | _stringĀ |Ā number_ | Applies [max-height][max-height-mdn] |
| minHeight | _stringĀ |Ā number_ | Applies [min-height][min-height-mdn] |
| width | _stringĀ |Ā number_ | Applies [width][width-mdn] |
| maxWidth | _stringĀ |Ā number_ | Applies [max-width][max-width-mdn] |
| minWidth | _stringĀ |Ā number_ | Applies [min-width][min-width-mdn] |
| m, margin | _stringĀ |Ā number_ | Applies margin using CSS [margin][margin-mdn] shorthand specification |
| mt, marginTop | _stringĀ |Ā number_ | Applies margin using CSS [margin-top][margin-top-mdn] specification |
| mr, marginRight | _stringĀ |Ā number_ | Applies margin using CSS [margin-right][margin-right-mdn] specification |
| mb, marginBottom | _stringĀ |Ā number_ | Applies margin using CSS [margin-bottom][margin-bottom-mdn] specification |
| ml, marginLeft | _stringĀ |Ā number_ | Applies margin using CSS [margin-left][margin-left-mdn] specification |
| p, padding | _stringĀ |Ā number_ | Applies padding using CSS [padding][padding-mdn] shorthand specification |
| pt, paddingTop | _stringĀ |Ā number_ | Applies padding using CSS [padding-top][padding-top-mdn] specification |
| pr, paddingRight | _stringĀ |Ā number_ | Applies padding using CSS [padding-right][padding-right-mdn] specification |
| pb, paddingBottom | _stringĀ |Ā number_ | Applies padding using CSS [padding-bottom][padding-bottom-mdn] specification |
| pl,paddingLeft | _stringĀ |Ā number_ | Applies padding using CSS [padding-left][padding-left-mdn] specification |
| border | _stringĀ |Ā number_ | Applies border using CSS [border][border-mdn] shorthand specification |
### FlexBox
- All props are **optional**.
- All boolean props defaults to **false**.
- All [Box](#box) props are also applicable.
| Props | Type | Description |
| -------------- | :------------------------------: | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| inline | _boolean_ | If true, applies `display: inline-flex` rule otherwise applies `display: flex` |
| column | _boolean_ | If true, `flex-direction` rule is set as `column` otherwise set as `row` |
| reverse | _boolean_ | It works in tandem with `column` prop to generate `flex-direction: {row\|column}-reverse`. Following table summaries it,
columnreverseflexādirectionfalsefalserowfalsetruerow-reversetruefalsecolumntruetruecolumn-reverse |
| wrap | _boolean_ | If true, applies `flex-wrap` as `wrap` |
| wrapReverse | _boolean_ | If true, applies `flex-wrap` as `wrap-reverse` |
| center | _boolean_ | If true, then applies `justify-content: center` and `align-items: center` |
| gap | _stringĀ |Ā number_ | Applies gap using CSS [gap][gap-mdn] shorthand specification if browser supports it, otherwise fallbacks to using margin property. Read [flex gap feature](#supports-flex-gap-feature) to understand more |
| columnGap | _stringĀ |Ā number_ | Applies CSS [column-gap][column-gap-mdn] property if browser supports it, otherwise fallbacks to using margin property. Read [flex gap feature](#supports-flex-gap-feature) to understand more |
| rowGap | _stringĀ |Ā number_ | Applies CSS [row-gap][row-gap-mdn] property if browser supports it, otherwise fallbacks to using margin property. Read [flex gap feature](#supports-flex-gap-feature) to understand more |
| justifyItems | _string_ | Applies `justify-items` rule. Depending on the browser, [these justify-items][justify-items-mdn] values might be supported |
| justifyContent | _string_ | Applies `justify-content` rule. Depending on the browser, [these justify-content][justify-content-mdn] values might be supported |
| alignItems | _string_ | Applies `align-items` rule. Depending on the browser, [these align-items][align-items-mdn] values might be supported |
| alignContent | _string_ | Applies `align-content` rule. Depending on the browser, [these align-content][align-content-mdn] values might be supported |
### FlexItem
- All props are **optional**.
- All boolean props defaults to **false**.
- All [Box](#box) props are also applicable.
- All [FlexBox](#flexBox) props are applicable if `box` prop is set to true.
| Props | Type | Description |
| ----------- | :------------------------------: | ------------------------------------------------------------------------------------------------------------------------ |
| flex | _stringĀ |Ā number_ | Applies flex using CSS [flex][flex-prop-mdn] shorthand specification |
| grow | _stringĀ |Ā number_ | Applies CSS [flex-grow][flex-grow-mdn] property |
| shrink | _stringĀ |Ā number_ | Applies CSS [flex-shrink][flex-shrink-mdn] property |
| basis | _stringĀ |Ā number_ | Applies CSS [flex-basis][flex-basis-mdn] property |
| order | _stringĀ |Ā number_ | Applies CSS [order][order-mdn] property |
| justifySelf | _string_ | Applies `justify-self` rule. Depending on the browser, [these justify-self][justify-self-mdn] values might be supported. |
| alignSelf | _string_ | Applies `align-self` rule. Depending on the browser, [these align-self][align-self-mdn] values might be supported |
| box | _boolean_ | If true, then FlexItem also behaves as a FlexBox. In addition to FlexItem props, all the FlexBox props are applicable |
## š½ Features explained
### Supports unitless values
- **react-styled-flex** supports unitless values where units are required. In that case value will be auto suffixed with with `px` unit.
- Only values where unites are required(eg. **height, width, margin**) will be suffixed.
- CSS rules which don't have units won't be suffixed (eg. **order**)
### Supports flex gap feature
- Browser supports flex gap feature
- If [flex gap feature][flex-gap] is supported in browser than gap, columnGap and rowGap props will function as per specification.
- Browser don't support flex gap feature
- If browser does not supports it, then we intend to provide graceful degradation of flex gap feature by setting margin. This fallback is provided only if, either of **gap props** is set and **wrap** prop is not set.
- If **wrap** is set then gap wont work in non-supported browser.
- Rest all props are supported.
### Change underlying element
By default `FlexBox` and `FlexItem` renders div in the DOM. We can change it to any HTML element or react component using `styled-components` [as][styled-components-as-prop] prop.\
Example:
```jsx
import { FlexBox, FlexItem } from 'react-styled-flex';
/* other logic */
Child 1
Child 2
;
```
Renders `Child 1` and `Child 2` as button. Similarly any react component can be rendered.
## ā FAQ
### Where can I find examples ?
Working example of `react-styled-flex` with frameworks like `create-react-app`, `gatsby`, `next.js`, `parcel` can be found in [examples](/examples) directory of this repo. Both javascript and typescript variants are available. If any cool react framework is missing, raise a PR, we will be happy to get added.
### Why unstyled content appears during initial page render ?
In SSR or SSG rendering, web pages may [flash unstyled content][fouc] for brief moment of time when page layout is done using `react-styled-flex` `gap` prop. Though web page corrects itself as soon as react hydration runs, the shift may be distracting for end users.

In order to fix this issue, we have to provide css class `flex-gap-not-supported` to body tag.\
Below are the fixes available for next.js and gatsby.
next.js
Add custom `Document` to your application within `pages/_document.js`. Here is the minimal `_document` example
```jsx
// pages/_document.js
import Document, { Html, Head, Main, NextScript } from 'next/document';
import { FlexGapNotSupportedClassName } from 'react-styled-flex';
export default class MyDocument extends Document {
static async getInitialProps(ctx) {
const initialProps = await Document.getInitialProps(ctx);
return { ...initialProps };
}
render() {
return (
);
}
}
```
gatsby
Customize `gatsby-ssr.js` module to implement `onRenderBody` API. Minimal example is shown below:
```jsx
// gatsby-ssr.js
const React = require('react');
const { FlexGapNotSupportedClassName } = require('react-styled-flex');
exports.onRenderBody = ({ setBodyAttributes }) => {
setBodyAttributes({
className: FlexGapNotSupportedClassName,
});
};
```
You may also refer to examples directory for complete working demo.
## āļø License
MIT Ā© Piyush Lodaya
## š Resources
- [A Complete Guide to Flexbox][flex-guide-css-tricks]
- [CSS Flexible Box Layout][flex-guide-mdn]
[npm]: https://img.shields.io/npm/v/react-styled-flex
[npm-url]: https://www.npmjs.com/package/react-styled-flex
[size-min]: https://img.shields.io/bundlephobia/min/react-styled-flex@latest
[size-minzip]: https://img.shields.io/bundlephobia/minzip/react-styled-flex@latest
[bundlephobia-url]: https://bundlephobia.com/result?p=react-styled-flex@latest
[package-types]: https://img.shields.io/npm/types/react-styled-flex
[codacy]: https://api.codacy.com/project/badge/Grade/3883d0db80a44fa6b18a311be25a8553
[codacy-url]: https://www.codacy.com/manual/ppiyush13/react-styled-flex?utm_source=github.com&utm_medium=referral&utm_content=ppiyush13/react-styled-flex&utm_campaign=Badge_Grade
[build]: https://circleci.com/gh/ppiyush13/react-styled-flex/tree/master.svg?style=shield
[build-url]: https://circleci.com/gh/ppiyush13/react-styled-flex/tree/master
[coverage]: https://codecov.io/gh/ppiyush13/react-styled-flex/branch/master/graph/badge.svg
[coverage-url]: https://codecov.io/gh/ppiyush13/react-styled-flex
[styled-components-git]: https://github.com/styled-components/styled-components
[react-git]: https://github.com/facebook/react
[flex-gap]: https://developer.mozilla.org/en-US/docs/Web/CSS/gap#Flex_layout
[styled-components-npm]: https://www.npmjs.com/package/styled-components
[react-npm]: https://www.npmjs.com/package/react
[box-sizing-mdn]: https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing#syntax
[position-mdn]: https://developer.mozilla.org/en-US/docs/Web/CSS/position#syntax
[height-mdn]: https://developer.mozilla.org/en-US/docs/Web/CSS/height#syntax
[max-height-mdn]: https://developer.mozilla.org/en-US/docs/Web/CSS/max-height#syntax
[min-height-mdn]: https://developer.mozilla.org/en-US/docs/Web/CSS/min-height#syntax
[width-mdn]: https://developer.mozilla.org/en-US/docs/Web/CSS/width#syntax
[max-width-mdn]: https://developer.mozilla.org/en-US/docs/Web/CSS/max-width#syntax
[min-width-mdn]: https://developer.mozilla.org/en-US/docs/Web/CSS/min-width#syntax
[padding-mdn]: https://developer.mozilla.org/en-US/docs/Web/CSS/padding#Syntax
[padding-top-mdn]: https://developer.mozilla.org/en-US/docs/Web/CSS/padding-top#syntax
[padding-right-mdn]: https://developer.mozilla.org/en-US/docs/Web/CSS/padding-right#syntax
[padding-bottom-mdn]: https://developer.mozilla.org/en-US/docs/Web/CSS/padding-bottom#syntax
[padding-left-mdn]: https://developer.mozilla.org/en-US/docs/Web/CSS/padding-left#syntax
[margin-mdn]: https://developer.mozilla.org/en-US/docs/Web/CSS/margin#Syntax
[margin-top-mdn]: https://developer.mozilla.org/en-US/docs/Web/CSS/margin-top#Syntax
[margin-right-mdn]: https://developer.mozilla.org/en-US/docs/Web/CSS/margin-right#Syntax
[margin-bottom-mdn]: https://developer.mozilla.org/en-US/docs/Web/CSS/margin-bottom#Syntax
[margin-left-mdn]: https://developer.mozilla.org/en-US/docs/Web/CSS/margin-left#Syntax
[border-mdn]: https://developer.mozilla.org/en-US/docs/Web/CSS/border#Syntax
[justify-items-mdn]: https://developer.mozilla.org/en-US/docs/Web/CSS/justify-items#values
[justify-content-mdn]: https://developer.mozilla.org/en-US/docs/Web/CSS/justify-content#Values
[align-items-mdn]: https://developer.mozilla.org/en-US/docs/Web/CSS/align-items#Values
[align-content-mdn]: https://developer.mozilla.org/en-US/docs/Web/CSS/align-content#Values
[gap-mdn]: https://developer.mozilla.org/en-US/docs/Web/CSS/gap#Syntax
[row-gap-mdn]: https://developer.mozilla.org/en-US/docs/Web/CSS/row-gap#Syntax
[column-gap-mdn]: https://developer.mozilla.org/en-US/docs/Web/CSS/column-gap#Syntax
[order-mdn]: https://developer.mozilla.org/en-US/docs/Web/CSS/order#Syntax
[flex-prop-mdn]: https://developer.mozilla.org/en-US/docs/Web/CSS/flex#Syntax
[flex-grow-mdn]: https://developer.mozilla.org/en-US/docs/Web/CSS/flex-grow#Syntax
[flex-shrink-mdn]: https://developer.mozilla.org/en-US/docs/Web/CSS/flex-shrink#Syntax
[flex-basis-mdn]: https://developer.mozilla.org/en-US/docs/Web/CSS/flex-basis#Syntax
[justify-self-mdn]: https://developer.mozilla.org/en-US/docs/Web/CSS/justify-self#values
[align-self-mdn]: https://developer.mozilla.org/en-US/docs/Web/CSS/align-self#Values
[flex-guide-css-tricks]: https://css-tricks.com/snippets/css/a-guide-to-flexbox/
[flex-guide-mdn]: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout
[version-1-docs]: https://github.com/ppiyush13/react-styled-flex/blob/v1/README.md
[styled-components-should-forward-prop]: https://styled-components.com/docs/api#shouldforwardprop
[styled-components-as-prop]: https://styled-components.com/docs/api#as-polymorphic-prop
[fouc]: https://en.wikipedia.org/wiki/Flash_of_unstyled_content