Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
8 contributors

Users who have contributed to this file

@threepointone @kentcdodds @seldo @tanem @mayase @joecritch @iest @bvaughn
447 lines (347 sloc) 6.01 KB

// css vs glamor

apply a style to an element

css

.box { color: red; }
<div class='box'> 
  this is a nice box. 
<div>

glamor

import { css } from 'glamor'

let box = css({ color: 'red' })
// ...
<div {...box}>
  this is a nice box. 
</div>

// or 
<div className={box}>
  this is a nice box. 
</div>

pseudoclasses

css

.box:hover { color: blue; }

glamor

import { css } from 'glamor'

let boxHover = css({ 
  ':hover': {
    color: 'blue' 
  } 
})

// or 

import { hover } from 'glamor'
let boxHover = hover({ color: 'blue' })

multiple styles to an element

css

<div class="bold myClass"/>

glamor

import { css } from 'glamor'

<div {...bold} {...myClass} />

// or, unlike css, to maintain precendence order 

<div {...css(bold, myClass)} />

// also works with classes

<div className={css(bold, myClass)} />

(more examples for composing rules)

child selectors

css

#box { display: block; }
.bold { font-weight: bold; }
.one  { color: blue; }
#box:hover .two { color: red; }
<div id="box">
  <div class="one bold">is blue-bold!</div>
  <div class="two">hover red!</div>
</div>

glamor

import { css } from 'glamor'

let box = css({
  display: 'block',
  '& .bold': { fontWeight: 'bold' },
  '& .one': { color: 'blue' },
  ':hover .two': { color: 'red' }
})

// or 
import { css, select as $ } from 'glamor'
let box = css(
  { display: 'block' },
  $('& .bold', { fontWeight: 'bold' }),
  $('& .one', { color: 'blue' }),
  $(':hover .two', { color: 'red' }),  
)


// ...

<div {...box}>
  <div className="one bold">is blue-bold!</div>
  <div className="two">hover red!</div>
</div>

It's also possible to use Glamor's generated classNames for nested styles:

glamor

import { css } from 'glamor'

const child = css({
  // Child styles ...
});
const parent = css({
  // Parent styles ...

  [`& .${child}`]: {
    // Nested child styles
  }
});

// ...

<div className={parent}>
  <div className={child}>...</div>
</div>

your components could also accept props to be merged into the component

let defaultStyle = { color: 'blue' }
export const Button = ({ css, children, ...props }) => 
  <button {...props} {merge(defaultStyle, css)}>
    {children}
  </button>

<Button css={hover({ color: 'red' })} />

[todo - vars and themes]

parent selectors

css

.no-js .something #box { color: gray; }

glamor

import {css, parent} from 'glamor'

let box = css({
  '.no-js .something &': { color: 'gray' }
})

// or 

import { css, parent } from 'glamor'

let box = parent('.no-js .something', 
  { color: 'gray' })

<div {...box} /> 

siblings

use + and ~ selectors

css

.list li:first-of-type + li {
  color: red
}
<ul class='list'>
  <li>one</li>
  <li>two - red!</li>
  <li>three</li>
</ul>

glamor

import {select as $} from 'glamor'

let ul = $('& li:first-of-type + li', {
  color: 'red'
})

// ...

<ul {...ul}>
  <li>one</li>
  <li>two - red!</li>
  <li>three</li>  
</ul>

media queries

css

.box {
  position: 'relative',
  width: '100%',
  maxWidth: 960,
  margin: '0 auto',
  padding: '0 20px',
  boxSizing: 'border-box'
}

.box:after {
  content: '""',
  display: 'table',
  clear: 'both'
}

@media (min-width: 400px) {
  .box {
    width: 85%;
    padding: 0
  }
}

@media (min-width: 550px) {
  .box:nth-child(2n) {
    width: 80%
  }
}

glamor

import {css, after, media, nthChild} from 'glamor'

const container = css(
  {
    position: 'relative',
    width: '100%',
    maxWidth: 960,
    margin: '0 auto',
    padding: '0 20px',
    boxSizing: 'border-box'
  },
  after({
    content: '""',
    display: 'table',
    clear: 'both'
  }),
  { 
    '@media(min-width: 400px)': {
      width: '85%',
      padding: 0
    }
  },
  // or use helpers 
  media('(min-width: 550px)', nthChild('2n', {
    width: '80%'    
  }))  
)

:global css rule

css

html, body { padding: 0 }

glamor

import { css } from 'glamor'

css.global('html, body',  { padding: 0 })
// or as raw css
css.insert('html, body { padding: 0 }')

fallback values

css

.box {
  display: flex;
  display: block;
}

glamor

let box = style({
  display: ['flex', 'block']
})

font-face

[todo]

animations

css

@keyframes bounce { 
  0%: { transform: scale(0.1); opacity: 0; }
  60%: { transform: scale(1.2); opacity: 1; }
  100%: { transform: scale(1); }
}

.box {
  animation: bounce 2s;
  width: 50px;
  height: 50px;
  backgroundColor: 'red';
}

glamor

let bounce = css.keyframes({ 
  '0%': { transform: 'scale(0.1)', opacity: 0 },
  '60%': { transform: 'scale(1.2)', opacity: 1 },
  '100%': { transform: 'scale(1)' }
})

let box = css({
  animation: `${bounce} 2s`,
  width: 50,
  height: 50,
  backgroundColor: 'red'
}) 

css reset / normalize

import `glamor/reset`

fallbacks

css

.abc {
  color: #ccc;
  color: rgba(0, 0, 0, 0.5);
}

glamor

let abc = css({
  color: ['#ccc', 'rgba(0, 0, 0, 0.5)']
})

combined selectors

css

.f1 { font-size: 1rem };
.red { background: red };
.f1.red { font-size: 2rem };
<div class="f1 red">
  I'm red and 2rem!
</div>

glamor

// With regular selectors (not ideal for namespacing/isolation)
const rule = style({
  '&.f1' : { fontSize: '1rem' },
  '&.red' : { background: 'red' },
  '&.f1.red' : { fontSize: '2rem' }
 })

<div class={`${rule} f1 red`}></div>


// Or use merge to output a single css selector
const f1 = ({ fontSize: '1rem' });
const red = ({ background: 'red' });
const f1Red = merge(f1, red, { fontSize: '2rem' });

<div class={rule}></div>


// Or for a more traditional css approach...
const f1 = ({ fontSize: '1rem' });
const red = ({ background: 'red' });
const f1Red = style({
  [`&.${f1}.${red}`]: { fontSize: '2rem' }
});

// ...but you still have to use all three selectors
<div class={`${f1} ${red} ${f1red}`}></div>
You can’t perform that action at this time.