import * as React from 'react';
import { CodeSnippet } from '@fluentui/docs-components';
import { Button, Box, Flex, Header, Segment, Divider } from '@fluentui/react-northstar';
import ExampleSnippet from '../components/ExampleSnippet';
import DocPage from '../components/DocPage';
import GuidesNavigationFooter from '../components/GuidesNavigationFooter';
import { code, link } from '../utils/helpers';
import { EmojiIcon } from '@fluentui/react-icons-northstar';
const links = {
flex: link('Flex', '/components/flex'),
flexItem: link('Flex.Item', '/components/flex'),
grid: link('Grid', '/components/grid'),
segment: link('Segment', '/components/segment'),
box: link('Box', '/components/segment'),
};
export default () => (
The following components are introduced by Fluent UI to handle layout aspects:
Sometimes it might not be evident if some particular case is a case of 1D (i.e. {code('Flex')}) or 2D (i.e.{' '}
{code('Grid')}) layout. As a result, quite often {code('Grid')} component is used at places where it is sufficient
to use {code('Flex')}.
Here is the question you might ask yourself to decide on that:
{links.segment} and {links.box} components may be abused for layout purposes, like in the following examples:
While it might seem that the intent is addressed with the approach taken, however, this is wrong for the following
reason:
If we'd refer to the semantics provided in the description for {links.segment} component:
This description suggests that purpose of {code('Segment')} is not a layout. Thus, this component shouldn't be
used for layout purposes, as this will break component's semantics - and, as a consequence, it might break
accessibility and theming, as those both adhere to component's semantics at the first place.
Same conclusions applies to the {links.box} component.
There is no strict need to use {code('Flex.Item')} component as a direct child of {code('Flex')} - one may use{' '}
{code('Flex.Item')} component only when it is necessary to tweak flex styles of individual child item.
As a consequence of this:
Flex component was designed being able to address all flexbox layout scenarios with minimal amount of DOM elements
rendered. In addition, there are props to address most common{' '}
{link(
'flexbox usage scenarios',
'https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Typical_Use_Cases_of_Flexbox',
)}{' '}
(e.g. {code('push')} prop) - the value of these props is that they introduce the least amount of DOM elements
necessary to accomplish corresponding use-case.
Let's consider one of the most representative examples - a navigation menu. Suppose that we want a menu bar with
logo on the left side and set of nav links on the right.
Quite often this is achieved by introducing a top-level flex container with two children: first is a logo, and the
second one is another container ({code('Flex')}, renders to {code('
Fluent UI makes it very important to follow component's semantics at the first place, and only
then consider the visual aspects.
A segment is used to create a grouping of related content.
Use {code('Flex.Item')} component to wrap child elements only in case if their flex styles should be overriden.
Each {code('Flex.Item')} element being introduced without any props specified should be considered for removal.
It turns out that this approach introduces unnecessary nesting level - it is possible to achieve the same goal by using just top-level container, with no buttons container:
Note that {code('Flex.Item')} doesn't result in any additional DOM element rendered - its sole purpose is just to pass style props to its child.
Consider to review set of examples on the {links.flex} page - as there might be an example that suits your needs.{' '} Each of these examples is optimized in terms of DOM elements rendered.