Skip to content

Instantly share code, notes, and snippets.

@RussMax783
Created January 26, 2017 22:17
Show Gist options
  • Save RussMax783/23aabe411eed10fd4b85e9507c372deb to your computer and use it in GitHub Desktop.
Save RussMax783/23aabe411eed10fd4b85e9507c372deb to your computer and use it in GitHub Desktop.

#Layout Component:

Internal Layout Styles:

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.

Internal layout styles include:

  • alignContent
  • alignItems
  • display (flex)
  • flex
  • flexBasis
  • flexDirection
  • flexGrow
  • flexShrink
  • flexWrap
  • height
  • justifyContent
  • maxHeight
  • maxWidth
  • minHeight
  • minWidth
  • order
  • padding
  • paddingBottom
  • paddingLeft
  • paddingRight
  • paddingTop
  • width

Example:

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 Layout Styles:

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.

External layout styles include:

  • margin
  • float
  • position
  • top
  • left
  • bottom
  • right
  • alignSelf

Example:

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

Flex Library Components:

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!

<Flex>

A lower level component that other higher level components extend from. YOU SHOULD NEVER USE THIS!!!
Defaults:
  • display: flex
Props:
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,

<Row>

Aligns all children into a row, following the x axis.
Defaults
  • flexDirection: 'row'
props
  • alignItems
  • alignContent
  • flex
  • flexWrap
  • justifyContent

<Col>

Aligns all children into a column, following the y axis.
Defaults
  • flexDirection: 'column'
props
  • alignItems
  • alignContent
  • flex
  • flexWrap
  • justifyContent

<Grid>

Aligns all children into a grid system

<Fill>

Take as much space as we can
Defaults
  • flex: '1 1 auto'

What else ???

questions:

  • 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment