#Layout Component:
Internal styles are styles that are applied to a component to style all its inner (immediate) children from border inward. The goal of this is to keep components as dynamic as possible by only defining what itself should always look like. We don't worry about where it is on the page or how is should look along side other components.
- alignContent
- alignItems
- display (flex)
- flex
- flexBasis
- flexDirection
- flexGrow
- flexShrink
- flexWrap
- height
- justifyContent
- maxHeight
- maxWidth
- minHeight
- minWidth
- order
- padding
- paddingBottom
- paddingLeft
- paddingRight
- paddingTop
- width
Lets say we want to create a rating component that displays 5 stars in a row based on a rating. You can simply accomplish this task but wrapping 5 star elements in a div that has styles set to: display: flex, flexDirection: row
.
<div style={{display: 'flex', flexDirection: 'row'}}>
<Star/>
<Star/>
<Star/>
<Star/>
<Star/>
</div>
BAM! Done!
Lets complicate it a little and say that the stars should be spaced evenly over 100% width.
<div style={{display: 'flex', flexDirection: 'row', width: '100%', justifyContent: 'space-around'}}>
<Star/>
<Star/>
<Star/>
<Star/>
<Star/>
</div>
Super easy! This is because we don't care about the context that the stars element is in. We only care what the stars component looks like. We add no external layout styles (see below) which allows us the ability to reuse this component in any context!**
External styles are styles that are applied to a component that position it acording to its siblings. This means that a container component should never add padding or any other style that will effect the internals of the component it is wrapping. Following this rule will keep layout standard across the site and hopefully reduce side effects of css.
- margin
- float
- position
- top
- left
- bottom
- right
- alignSelf
Lets take our <Stars/>
component. We would like to position it next to a seller image with a space of 40px between the image and the stars and would also like it to align itself center like so:
- - - SellerOverview - - - - - - - - - - -
| _ _ _ _ |
| | sllr | |
| | img | --40px-- * * * * * --40px-- |
| |_ _ _ _| |
| |
- - - - - - - - - - - - - - - - - - - - -
Now, <SellerOverview/>
wouldn't use any external styles on itself because remember, all components must style inward from border. We use display: flex, flexDirection: row, alignContent: center
and wrap <SellerImage/>
and <Stars/>
because we want them in a centered vertical row. We can apply padding: 10px
because no matter what we always want 10px surrounding the top and sides of <SellerImage />
.
<div style={{ padding: 10, display: 'flex', flexDirection: 'row', alignContent='center' }}>
<Image src={...} />
<Stars />
</div>
Up to this point we would have everything except for the 40 px in between the image and the stars. We could try and add justifyContent="space-around"
or something similar but that wouldn't give us what we want because it should always be 40px. This is where we can use external styles. In order to have the 40px left and right of the <Stars/>
, we add a marginLeft and marginRight directly to the stars component. This is legal because the parent (<SellerOverview/>
)is effecting the external style of the <Stars/>
component, which is an immediate child. This now allows us to use the <Stars/>
component in another place on our site that has a different margin or position or completely different context!
<div style={{ padding: 10, display: 'flex', flexDirection: 'row', alignContent='center' }}>
<Image src={...} />
<Stars style={{margin: '0 40px'/>
</div>
The question comes on wether we should use className or styles to pass external styles down to components? Im open to suggestions
The purpose of the flex library is to provide common patterns to help quickly layout a page without worrying about or duplicating css. How often do you use display flex, flex-direction row, or justify-content? ALOT!
A lower level component that other higher level components extend from. YOU SHOULD NEVER USE THIS!!!
- display: flex
alignContent: PropTypes.oneOf([
'center',
'flex-end',
'flex-start',
'space-around',
'space-between',
'stretch',
]),
alignItems: PropTypes.oneOf([
'baseline',
'center',
'flex-end',
'flex-start',
'stretch',
]),
flex: PropTypes.string,
flexBasis: PropTypes.string,
flexDirection: PropTypes.oneOf([
'column-reverse',
'column',
'row-reverse',
'row',
]),
flexGrow: PropTypes.number,
flexShrink: PropTypes.number,
flexWrap: PropTypes.oneOf([
'nowrap',
'wrap-reverse',
'wrap',
]),
height: PropTypes.string,
inline: PropTypes.bool, // sets display: inline-flex
justifyContent: PropTypes.oneOf([
'center',
'flex-end',
'flex-start',
'space-around',
'space-between',
]),
maxHeight: PropTypes.string,
maxWidth: PropTypes.string,
minHeight: PropTypes.string,
minWidth: PropTypes.string,
padding: PropTypes.string,
paddingBottom: PropTypes.string,
paddingLeft: PropTypes.string,
paddingRight: PropTypes.string,
paddingTop: PropTypes.string,
width: PropTypes.string,
- flexDirection: 'row'
- alignItems
- alignContent
- flex
- flexWrap
- justifyContent
- flexDirection: 'column'
- alignItems
- alignContent
- flex
- flexWrap
- justifyContent
- flex: '1 1 auto'
- should we have the ability to expose an element prop to change the base element?
- There are some flex properties that aren't in use between row, col, and grid such as flex-grow. Do we want to allow row and grid to use those? or do we just not expose those and when that use case arises we can identify the context that it is in and create another higher level component?
** I understand that these are simple examples. but, if you visualize all your page/sections/components and how they fit together, you can construct and compose components together using internal and external layout styles to get complex layouts.