Vertical & Horizontal Stacks Components with React & FlexBox
Radzion Chachura
Posted on January 8, 2023
✨ Watch on YouTube | 🐙 GitHub | 🎮 Demo
Most web layout is a combination of grids and stacks of elements that we create with either CSS grid or flexbox. In this post, I want to share how to write significantly less CSS by leveraging Stack
components.
import styled, { css } from "styled-components"
import { getCSSUnit } from "lib/ui/utils/getCSSUnit"
interface Props {
gap?: React.CSSProperties["gap"]
alignItems?: React.CSSProperties["alignItems"]
justifyContent?: React.CSSProperties["justifyContent"]
wrap?: React.CSSProperties["flexWrap"]
children: React.ReactNode
fullWidth?: boolean
fullHeight?: boolean
}
const formatFlexAlignment = (
value:
| React.CSSProperties["alignItems"]
| React.CSSProperties["justifyContent"]
) => {
if (value === "end" || value === "start") {
return `flex-${value}`
}
return value
}
const stackCSS = css<Props>`
display: flex;
${({ gap }) =>
gap &&
css`
gap: ${getCSSUnit(gap)};
`}
${({ alignItems }) =>
alignItems &&
css`
align-items: ${formatFlexAlignment(alignItems)};
`}
${({ justifyContent }) =>
justifyContent &&
css`
justify-content: ${formatFlexAlignment(justifyContent)};
`}
${({ wrap }) =>
wrap &&
css`
flex-wrap: ${wrap};
`}
${({ fullWidth }) =>
fullWidth &&
css`
width: 100%;
`}
${({ fullHeight }) =>
fullHeight &&
css`
height: 100%;
`}
`
export const VStack = styled.div`
${stackCSS}
flex-direction: column;
`
export const HStack = styled.div`
${stackCSS}
flex-direction: row;
`
interface StackProps extends Props {
direction: React.CSSProperties["direction"]
}
export const Stack = styled.div<StackProps>`
${stackCSS}
flex-direction: ${({ direction }) => direction};
`
Here we have three components: VStack
, HStack
, and Stack
. While the first two have fixed directions, the Stack component receives a direction as a property. It could be helpful for responsive views, but I rarely use it since flex-wrap
is enough in most cases.
Both vertical and horizontal stacks have shared styles except flex-direction
property. These components have only optional properties and don't rewrite flexbox attributes unless there is a prop for it. To set types forgap
, alignItems
, justify-content
, and wrap
, we leverage React'sCSSProperties
. Often we want to make the stack take full width or height. Safaris don't support end and start values yet, so we have a formatFlexAlignment
helper that will add a flex prefix to them.
In my product at increaser.org, I use these components all the time. VStack
has 443 occurrences, and HStack
201.
Posted on January 8, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 30, 2024
November 30, 2024