Flex

Used for creating unidimensional layouts.

Usage

FlexExample.tsx
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
<Flex justify="between" items="center" gap="6" className="mt-4 h-24 rounded-md bg-slate-200 p-4">
<div className="h-10 w-10 rounded-sm bg-slate-600" />
<div className="h-10 w-10 rounded-sm bg-slate-600" />
<div className="h-10 w-10 rounded-sm bg-slate-600" />
<div className="h-10 w-10 rounded-sm bg-slate-600" />
<div className="h-10 w-10 rounded-sm bg-slate-600" />
</Flex>

Here's the <Flex /> component in action.

Features

  • Inherits the fluid space scale on the gap prop.
  • Removes inaccessible CSS features.

Accessibility

Changing visual order creates a disconnect between content and presentation and is, therefore, bad for accessibility. For this reason, the flex-direction: row-reverse and flex-direction: column-reverse options are omitted.

Parts and their API

Flex

Used for creating unidimensional layouts.

Props

PropTypeDefaultDescription
justify'start' | 'center' | 'end' | 'between''start'The alignment of items along the main axis.
items'start' | 'center' | 'end' | 'stretch''start'The alignment of items along the cross axis.
gap0 to 200The gap between items.
orientation'horizontal' | 'vertical''horizontal'The orientation of the layout.
inlinebooleanfalseWhether the flex layout is inline or not.
wrapbooleanfalseWhether items should wrap to multiple lines.

Wrap

Flexbox loses a lot of its power if you make it wrap. If you need to wrap, you should probably use a grid instead.

Notes

If you set <Flex inline />, the div has the least width possible, so the justify prop has no meaning because the items won't have any extra horizontal space for the justify option to matter.

If you set <Flex items="stretch" /> and the children have a fixed height, items="stretch" will be ignored.

Source

flex.tsx
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
  38. 38
  39. 39
  40. 40
  41. 41
  42. 42
  43. 43
  44. 44
  45. 45
  46. 46
  47. 47
  48. 48
  49. 49
  50. 50
  51. 51
  52. 52
  53. 53
  54. 54
  55. 55
  56. 56
  57. 57
  58. 58
  59. 59
  60. 60
  61. 61
  62. 62
  63. 63
  64. 64
  65. 65
  66. 66
  67. 67
  68. 68
  69. 69
  70. 70
  71. 71
  72. 72
  73. 73
  74. 74
  75. 75
  76. 76
  77. 77
  78. 78
  79. 79
  80. 80
  81. 81
import { type VariantProps, cva } from 'class-variance-authority'
import { type HTMLAttributes, type PropsWithChildren, forwardRef } from 'react'
import { cn } from '#app/utils/tailwind-merge.ts'
const flexVariants = cva('flex', {
variants: {
orientation: {
horizontal: 'flex-row',
vertical: 'flex-col',
},
justify: {
start: 'justify-start',
center: 'justify-center',
end: 'justify-end',
between: 'justify-between',
},
items: {
start: 'items-start',
center: 'items-center',
end: 'items-end',
baseline: 'items-baseline',
stretch: 'items-stretch',
},
gap: {
'0': 'gap-0',
'1': 'gap-fluid-1',
'2': 'gap-fluid-2',
'3': 'gap-fluid-3',
'4': 'gap-fluid-4',
'5': 'gap-fluid-5',
'6': 'gap-fluid-6',
'7': 'gap-fluid-7',
'8': 'gap-fluid-8',
'9': 'gap-fluid-9',
'10': 'gap-fluid-10',
'11': 'gap-fluid-11',
'12': 'gap-fluid-12',
'13': 'gap-fluid-13',
'14': 'gap-fluid-14',
'15': 'gap-fluid-15',
'16': 'gap-fluid-16',
'17': 'gap-fluid-17',
'18': 'gap-fluid-18',
'19': 'gap-fluid-19',
'20': 'gap-fluid-20',
},
},
})
type FlexProps = { inline?: boolean; wrap?: boolean } & VariantProps<typeof flexVariants> & PropsWithChildren<HTMLAttributes<HTMLDivElement>>
/**
* Flex component for creating unidimensional layouts.
*
* @component
* @example
* ```jsx
* <Flex justify="between" items="center" gap="6">
* <div>Item 1</div>
* <div>Item 2</div>
* <div>Item 3</div>
* </Flex>
* ```
*
* @param {string} [justify] - The alignment of items along the main axis. Can be 'start', 'center', 'end', or 'between'.
* @param {string} [items] - The alignment of items along the cross axis. Can be 'start', 'center', 'end', 'baseline', or 'stretch'.
* @param {string} [gap='0'] - The gap between items. Can be a number from 0 to 20.
* @param {string} [orientation='horizontal'] - The orientation of the flex container. Can be 'horizontal' or 'vertical'.
* @param {boolean} [inline=false] - Whether the flex container should be displayed as an inline element.
* @param {boolean} [wrap=false] - Whether items should wrap to multiple lines.
* @param {string} [className] - Additional CSS class names.
* @param {React.HTMLAttributes<HTMLDivElement>} [props] - Additional HTML attributes.
* @returns {JSX.Element} The Flex component.
*/
const Flex = forwardRef<HTMLDivElement, FlexProps>(({ inline = false, wrap = false, orientation = 'horizontal', justify, items, gap = '0', className, ...props }, ref) => {
return <div ref={ref} className={cn(flexVariants({ orientation, items, justify, gap }), inline ? `inline-flex` : ``, wrap ? `flex-wrap` : ``, className)} {...props} />
})
Flex.displayName = 'Flex'
export { Flex }