Description
To make it easier to build application layout and form-views in line with defined design sketches, there are a number of components for layout.
Wrappers
-
Card is a block section element showing the white box with rounded gray borders, adding spacing automatically.
-
Stack is an outer block element for wrapping content to get the correct layout and spacing between region and region headings.
Flex layout
-
Flex.Container is a building block for CSS flexbox based layout of contents and components.
<Flex.Vertical>
can be used as an alias instead of the propertydirection="vertical"
.<Flex.Horizontal>
can be used as an alias instead of the propertydirection="horizontal"
.
-
Flex.Item is a building block for CSS flexbox based layout of contents and components.
Grid layout
-
GridContainer is a layout system for CSS grid based layout of contents.
-
GridItem is a layout system for CSS grid based layout of contents.
Columns
UX designers are using a 12 column system, along with a 4 and 6 column system, during their design processes.
What are the differences between Flex and Grid?
Both to support different sizing of items on different media breakpoints.
Flex
Uses CSS flexbox
.
- Best suited for Forms layout.
- Can either stack vertically or horizontally.
- Can be used with any kind of children.
- Even distribution of space.
- Keeps order of items like they where given in the DOM structure.
- Items can be sized in percentage.
- When a size (percentage) is given, they stack horizontally.
import { Flex } from '@dnb/eufemia'render(<Flex.Container><Flex.Item>content</Flex.Item><OtherComponent>content</OtherComponent></Flex.Container>,)
Grid
Uses CSS grid
.
- Best suited for applications with a column based layout.
- Columns do change between 4, 6 and 12 on the given size (media query) of the browser or screen size.
- GridContainer depends on GridItem (Item).
- Items do span from column a to b.
- Items can have different order in opposition from what's given in the DOM structure.
import { Layout } from '@dnb/eufemia'render(<Layout.GridContainer><Layout.GridItem>content</Layout.GridItem><Layout.GridItem>content</Layout.GridItem></Layout.GridContainer>,)
Units and responsiveness
Please – use rem
instead of px
for all of your custom CSS, and make sure;
- you always use the nearest half
rem
value, like 0.5rem, 1rem or 1.5rem and so forth. - you always get a total computed height within the grid.
This results in maintaining the integrity of the 8px base grid.
Exceptions
There are exceptions for when you define a "minimum" of an area, such as min-width
. Because it will increase in size when a larger browser font-size is used. In that case, user px
as your sizing unit.
Smaller Units
Sometimes you may need a compensation of only a few pixels. Heres how to calculate the correct rem values:
- 1px =
1/16x1
= 0.0625rem - 2px =
1/16x2
= 0.125rem - And so on ...
Demos
Used in forms
Profile
Name
More information
<Flex.Stack> <Form.MainHeading>Profile</Form.MainHeading> <Card stack> <Form.SubHeading>Name</Form.SubHeading> <Field.String label="Fornavn" value="John" /> <Field.String label="Etternavn" value="Smith" /> </Card> <Card stack> <Form.SubHeading>More information</Form.SubHeading> <Field.NationalIdentityNumber value="20058512345" /> <Field.Email value="john@smith.email" /> <Field.PhoneNumber value="+47 98765432" /> </Card> </Flex.Stack>
Responsive forms
Responsive GridContainer
<Layout.GridContainer rowGap columnGap> <Layout.GridItem span={{ small: [1, 2], medium: [1, 3], large: [1, 12], }} style={colors[0]} element={TestElement} > Item A </Layout.GridItem> <Layout.GridItem span={{ small: [3, 4], medium: [4, 6], large: [1, 4], }} style={colors[1]} element={TestElement} > Item B </Layout.GridItem> <Layout.GridItem span={{ small: [2, 3], medium: [4, 6], large: [5, 8], }} style={colors[2]} element={TestElement} > Item C </Layout.GridItem> <Layout.GridItem span={{ small: [1, 4], medium: [4, 6], large: [9, 12], }} style={colors[3]} element={TestElement} > Item D </Layout.GridItem> </Layout.GridContainer>
Responsive Flex.Item
With the default sizeCount
of 12 parts.
<Flex.Container> <Flex.Item size={8}> <TestElement style={colors[0]}>FlexItem (8)</TestElement> </Flex.Item> <Flex.Item size={4}> <TestElement style={colors[1]}>FlexItem (4)</TestElement> </Flex.Item> <Flex.Item size={{ small: 12, medium: 4, }} > <TestElement style={colors[2]}> FlexItem (small: 8, medium: 4) </TestElement> </Flex.Item> <Flex.Item size={{ small: 12, medium: 8, }} > <TestElement style={colors[3]}> FlexItem (small: 4, medium: 8) </TestElement> </Flex.Item> </Flex.Container>
Customized Flex.Item sizes
With a custom amount of 4 parts (sizeCount
) as well as custom breakpoints and media queries.
const breakpoints = { ...defaultBreakpoints, xsmall: '30em', } const queries = { ...defaultQueries, xsmall: { min: 0, max: 'xsmall', }, small: { min: 'xsmall', max: 'small', }, } const CustomMediaQuery = styled.div` display: flex; flex-direction: column; .dnb-flex-container[data-media-key='xsmall'] .dnb-flex-item--responsive { --size: var(--xsmall); } ` render( <CustomMediaQuery> <Flex.Container direction="horizontal" sizeCount={4} breakpoints={breakpoints} queries={queries} > <Flex.Item size={{ small: 2, medium: 3, large: 1, }} > <TestElement style={colors[0]}>FlexItem</TestElement> </Flex.Item> <Flex.Item size={{ small: 2, medium: 1, large: 2, }} > <TestElement style={colors[1]}>FlexItem</TestElement> </Flex.Item> <Flex.Item size={{ xsmall: 4, small: 2, medium: 1, large: 1, }} > <TestElement style={colors[2]}>FlexItem</TestElement> </Flex.Item> <Flex.Item size={{ xsmall: 4, small: 2, medium: 3, large: 4, }} > <TestElement style={colors[3]}>FlexItem</TestElement> </Flex.Item> </Flex.Container> </CustomMediaQuery>, )