Components

Flex

Flex component is used together with FlexItem to lay out other components in a flexible, and optionally responsive, manner.

Examples #

Import Syntax #

import Flex, { FlexItem } from 'mineral-ui/Flex';

Note

Layout components, like Flex, have no visual style. They are rendered with background colors and borders in the examples below for illustrative purposes.

Basic Usage #

Use Flex and FlexItem to lay out components throughout your app. They can be arranged side-by-side, stacked on top of one another, centered both horizontally and vertically, and lots more as illustrated in the further examples below.

A
B
C
<Flex>
  <FlexItem>A</FlexItem>
  <FlexItem>B</FlexItem>
  <FlexItem>C</FlexItem>
</Flex>

Direction #

Flex items can be laid out in a row (default) or column. Additionally, their flow can be reversed.

Accessibility Note

Exercise caution when using the "reverse" directions; they will flip the visual order while maintaining the semantic order. This can affect keyboard users because of a non-intuitive tab order as well as the order of content as recognized by assistive technologies.

A
B
C
A
B
C
A
B
C
A
B
C
() => {
  const propValues = [
    'row', // default
    'row-reverse',
    'column',
    'column-reverse'
  ];

  const renderFlexes = () =>
    propValues.map((value, index) => (
      <Flex direction={value} key={index}>
        <FlexItem>A</FlexItem>
        <FlexItem>B</FlexItem>
        <FlexItem>C</FlexItem>
      </Flex>
    ));

  return <DemoLayout>{renderFlexes()}</DemoLayout>;
}

Gutters #

Flex will add a default horizontal gap between items. Use the gutterWidth prop to define a different value, including 0 to disable gutters altogether.

Numbers will be appended with px. String values will be passed directly.

A
B
C
A
B
C
A
B
C
A
B
C
A
B
C
() => {
  const propValues = [
    'md', // default
    'xl',
    '2.5em',
    50,
    0
  ];

  const renderFlexes = () =>
    propValues.map((value, index) => (
      <Flex gutterWidth={value} key={index}>
        <FlexItem>A</FlexItem>
        <FlexItem>B</FlexItem>
        <FlexItem>C</FlexItem>
      </Flex>
    ));

  return <DemoLayout>{renderFlexes()}</DemoLayout>;
}

Justify Content #

The justifyContent prop defines the alignment of items along the main axis (horizontal, if direction is row; vertical, if direction is column).

A
B
C
A
B
C
A
B
C
A
B
C
A
B
C
A
B
C
A
B
C
A
B
C
A
B
C
A
B
C
A
B
C
A
B
C
() => {
  const propValues = [
    'start', // default
    'center',
    'end',
    'around',
    'between',
    'evenly'
  ];

  const renderFlexes = ({ column }) =>
    propValues.map((value, index) => (
      <Flex
        justifyContent={value}
        direction={column ? 'column' : 'row'}
        key={column ? 'c-' + index : index}>
        <FlexItem>A</FlexItem>
        <FlexItem>B</FlexItem>
        <FlexItem>C</FlexItem>
      </Flex>
    ));

  return (
    <DemoLayout>
      {renderFlexes({ column: false })}
      {renderFlexes({ column: true })}
    </DemoLayout>
  );
}

Align Items #

The alignItems prop defines the alignment of items along the cross axis (vertical, if direction is row; horizontal, if direction is column).

A
B
C
A
B
C
A
B
C
A
B
C
A
B
C
A
B
C
A
B
C
A
B
C
() => {
  const propValues = [
    'stretch', // default
    'start',
    'center',
    'end'
  ];

  const renderFlexes = ({ column }) => (
    propValues.map((value, index) => (
      <Flex
        alignItems={value}
        direction={column ? 'column' : 'row'}
        key={column ? 'c-' + index : index}>
        <FlexItem>A</FlexItem>
        <FlexItem>B</FlexItem>
        <FlexItem>C</FlexItem>
      </Flex>
    ))
  );

  return (
    <DemoLayout>
      { renderFlexes({ column: false }) }
      { renderFlexes({ column: true }) }
    </DemoLayout>
  )
}

Wrapping #

Flex items can optionally wrap to multiple lines along the main axis.

A
B
C
D
E
<Flex wrap>
  <FlexItem>A</FlexItem>
  <FlexItem>B</FlexItem>
  <FlexItem>C</FlexItem>
  <FlexItem>D</FlexItem>
  <FlexItem>E</FlexItem>
</Flex>

Box Props #

Because Flex composes the Box component, it accepts any of Box's props.

A
B
C
<div>
  {/* You can apply Box props directly to Flex: */}
  <Flex as="header" padding="lg" width={1/2}>
    <FlexItem>A</FlexItem>
    <FlexItem>B</FlexItem>
    <FlexItem>C</FlexItem>
  </Flex>

  {/* Don't wrap Flex in a Box to apply spacing/sizing props:
    <Box padding="lg" width={1/2}>
      <Flex>
        <FlexItem>A</FlexItem>
        <FlexItem>B</FlexItem>
        <FlexItem>C</FlexItem>
      </Flex>
    </Box>
  */}
</div>

Responsive #

Many of the properties for Flex can be responsive:

  1. Provide an array of breakpoints, which will be used in the (min-width) media queries used for responsive properties.
  2. Those breakpoint values can either be a number (converted to px) or a key from the theme (e.g. the default mineralTheme has 'narrow', 'medium', and 'wide').
  3. For each responsive property, instead of passing a single value, pass an array of values that is one longer than the breakpoints array. The first value applies when no breakpoint matches, the second value applies when the first breakpoint matches, and so on.
  4. If you don't need to change a value at a breakpoint, you can pass null to skip that breakpoint for that property.

The code in the example below exhibits the following behavior:

  1. When the viewport is less than 800px wide, it will display as a column.
  2. When the viewport is between 800px and 1024px (the 'wide' breakpoint theme variable), it will still display as a column because of the null value.
  3. When the viewport is at least 1024px wide, it will display as a row.
A
B
C
<Flex
  breakpoints={[800, 'wide']}
  direction={['column', null, 'row']}>
  <FlexItem>A</FlexItem>
  <FlexItem>B</FlexItem>
  <FlexItem>C</FlexItem>
</Flex>

Bidirectionality #

Flex reverses its alignment when the direction theme variable is set to rtl (right-to-left).

ا
ب
د
<div dir="rtl">
  <ThemeProvider theme={{ direction: 'rtl' }}>
    <Flex>
      <FlexItem>ا</FlexItem>
      <FlexItem>ب</FlexItem>
      <FlexItem marginStart="auto">د</FlexItem>
    </Flex>
  </ThemeProvider>
</div>

API & Theme #

Flex Props #

The Flex component takes the following React props.

NameTypeDefaultDescription
alignItems'stretch'

Align items along the cross axis [Responsive-capable]

breakpointsArray<number | string>

Media query (min-width) breakpoints along which to apply props marked "[Responsive-capable]"

childrenReact$Node

Must be FlexItem(s)

direction'row'

Direction of flow of items along the main axis [Responsive-capable]

gutterWidth'md'

Size of gap between children

justifyContent'start'

Align items along the main axis [Responsive-capable]

wrapboolean | Array<boolean | null>

Determines if items can wrap along main axis [Responsive-capable]

Note

In addition to the props above, Flex also accepts all props for Box.

Undocumented properties will be applied to the root element.

Usage #

When/How to Use #

Flex, together with FlexItem, provides an easy way to align components next to or on top of one another. With configurable gutters, many alignment options, and optionally responsive properties, it is powerful and flexible enough to be the foundation of your app's layout.

Best Practices #

Use Flex and FlexItem to arrange components next to one another, with a consistent gutter.

Don't use Flex and FlexItem to align components to a columnar layout. Use Grid and GridItem, instead.

Don't use Flex to align content to the left & right. StartEnd is a more appropriate choice.

Don't use Flex if the content being laid out should not respond to language direction.

Sidebar
Main Content