structure
npm install @plangrid/structure
-
main.css
is the production bundle - unpkg for codepen
CONTRIBUTING.md
- JavaScript API
Usage
- Favor flexbox for layout over other layout techniques
- Flexbox classes use pure flex properties to afford layouts in any direction or alignment
- Be aware of flexbugs and especially test complex layouts for browser differences
flex
balanced grid
<div class="flex">
<div class="flex-auto">item</div>
<div class="flex-auto">item</div>
<div class="flex-auto">item</div>
</div>
flex
wrapping grid
<div class="flex flex-wrap">
<div class="basis-4">grid item</div>
<div class="basis-4">grid item</div>
<div class="basis-4">grid item</div>
<div class="basis-4">grid item</div>
<div class="basis-4">grid item</div>
</div>
flex
reversing
<ol class="flex flex-column-reverse p0">
<li class="block p2 flex-auto">1</li>
<li class="block p2 flex-auto">2</li>
<li class="block p2 flex-auto">3</li>
</ol>
flex
centering
<div class="flex items-center justify-center">
<p>I'm centered :)
</div>
alignment
- Our alignment classes are useful for aligning flex items
- Properties include
align-items
align-content
align-self
justify-content
- Values include alignment values that are supportable by our browser coverage
- W3C categorizes values as positional | baseline | distribution
spacing
<figure class="m0 mb1 p2 pr4">
<figure class="p2 m0 mb1 mb0-last">content</figure>
<figure class="p2 m0 mb1 mb0-last">content</figure>
</figure>
Experimental: [data-spacing]
<Component data-spacing="mt0 mb2">
position
.static
.relative
.absolute
.fixed
-
.focus-static
for use like"relative focus-static"
to sink on focus -
.focus-relative
for use like"static focus-relative"
to lift on focus -
.top-auto
.left-auto
.right-auto
.bottom-auto
-
.top-0
.left-0
.right-0
.bottom-0
<div class="relative">
<div class="absolute top-0 left-0 right-0 bottom-0">I fill my container</div>
</div>
border
-
.border
Deprecated. Favorborder-1px border-solid
-
.border-top
Deprecated. Favorborder-1px bt-solid
-
.border-left
Deprecated. Favorborder-1px bl-solid
-
.border-right
Deprecated. Favorborder-1px br-solid
-
.border-bottom
Deprecated. Favorborder-1px bb-solid
-
.border-1px
is our standardborder-width
for any bordered component -
.border-none
.bt-none
.br-none
.bb-none
.bl-none
-
.border-dashed
.bt-dashed
.br-dashed
.bb-dashed
.bl-dashed
-
.border-solid
.bt-solid
.br-solid
.bb-solid
.bl-solid
-
.border-hidden
.bt-hidden
.br-hidden
.bb-hidden
.bl-hidden
border-radius
Round >=6px
to 12px
and <6px
to 3px
because 2px
3px
12px
are the most current sizes in our design system. Feature specs may be outdated. Please #truststructure
-
.rounded
Deprecated. Favorround-medium
-
.rounded-stack
Deprecated. Favorround-medium sharp-stack
-
.rounded-shelf
Deprecated. Favorround-medium sharp-shelf
-
.round-small
for2px
corners. Use on pills -
.round-medium
for3px
corners. Use on buttons, cards... -
.round-large
for12px
corners. Use on modals -
.round-circle
for50%
corners -
.sharp-top
zero top corners -
.sharp-left
zero left corners -
.sharp-right
zero right corners -
.sharp-bottom
zero bottom corners -
.sharp-shelf
zero interior shelf corners -
.sharp-stack
zero interior stack corners
<nav class="block p2 round-medium sharp-stack m-auto mt0 mb2">
<a class="block p2 round-medium sharp-stack mb1">top</a>
<a class="block p2 round-medium sharp-stack mb1">middle</a>
<a class="block p2 round-medium sharp-stack mb1">bottom</a>
</nav>
<div class="width-em height-em round-circle">circle</div>
border-width
Melding and welding refer to the union of borders between siblings. meld
and weld
do the same job but with opposing techniques. Compose them together to remove any inner borders. stack
affects vertical union. shelf
affects horizontal union.
-
.meld-stack
- meld stacked borders into one via:not(:first-child)
-
.meld-shelf
- meld shelved borders into one via:not(:first-child)
-
.weld-stack
- weld stacked borders into one via:not(:last-child)
-
.weld-shelf
- weld shelved borders into one via:not(:last-child)
<a class="block p2 border round-medium sharp-stack meld-stack">top</a>
<a class="block p2 border round-medium sharp-stack meld-stack">middle</a>
<a class="block p2 border round-medium sharp-stack meld-stack">bottom</a>
<a class="block p2 border round-medium sharp-shelf meld-shelf">left</a>
<a class="block p2 border round-medium sharp-shelf meld-shelf">right</a>
<a class="block p2 border round-medium sharp-shelf meld-shelf">bottom</a>
display
<label class="block">
<input class="inline-block mr1" type="checkbox" checked>
Use functional CSS
</label>
visibility
-
.vis-visible
default (element box is visible) -
.vis-hidden
invisible and inaccessible but retains layout -
.vis-collapse
invisible and inaccessible but retains flex strut or table layout with careful use
overflow
-
.overflow-visible
or per axis.ox-visible
.oy-visible
-
.overflow-hidden
or per axis.ox-hidden
.oy-hidden
-
.overflow-scroll
or per axis.ox-scroll
.oy-scroll
-
.overflow-auto
or per axis.ox-auto
oy-auto
-
.overflow-dots
setstext-overflow
toellipsis
-
.wrap-normal
setsoverflow-wrap
tonormal
-
.wrap-word
setsoverflow-wrap
tobreak-word
<div class="overflow-auto">
I scroll as needed.
</div>
<div class="oy-scroll">
I scroll vertically.
</div>
<div class="overflow-hidden overflow-dots ws-nowrap width-fit">
I truncate normally...
</div>
<div class="overflow-hidden overflow-dots ws-nowrap width-clip width-force">
I truncate specially...
</div>
white-space
.ws-normal
.ws-nowrap
.ws-pre
.ws-pre-wrap
.ws-pre-line
sizing
<div class="max-viewport min-zero width-all height-all">
example
</div>
float
We avoid floats where possible due to the abundance of more maintainable techniques such as flexbox for many scenarios. We provide .float-none
, .float-left
, .float-right
, .clearfix
for transitional use and special cases.
list-style
Use these on li
or its ul
or ol
to affect all children. These only apply when display
is list-item
. Avoid inside
when its children are block
because browsers vary in how inside blocks appear.
-
.list-disc
sets type todisc
(initial) -
.list-circle
sets type tocircle
-
.list-outside
sets position tooutside
(initial) -
.list-inside
sets position toinside
-
.list-none
sets style tonone
text-align
.text-left
.text-right
.text-center
vertical-align
Favor flexbox techniques for layout but know that these are available for finetuning.
-
.align-baseline
default .align-top
.align-middle
.align-bottom
.align-sub
.align-super
-
.align-ascent
fortext-top
-
.align-descent
fortext-bottom
font
- Display fonts are named in t-shirt sizes. See demo and round to the nearest fit :)
- Components may access via
import structure from "@plangrid/structure"
structure.bond("FontC") // "font-os font-c"
structure.bond("FontB") // "font-os font-b"
structure.bond("FontXXS") // "font-os font-xxs"
structure.bond("FontXS") // "font-os font-xs"
structure.bond("FontS") // "font-os font-s"
structure.bond("FontM") // "font-os font-m"
structure.bond("FontL") // "font-os font-l"
structure.bond("FontXL") // "font-os font-xl"
-
.font-c
is400 12px/1.25
none
-
.font-b
is400 14px/1.5
none
-
.font-xxs
is400 12px/1.25
uppercase
-
.font-xs
is600 16px/1.5
none
-
.font-s
is400 20px/1.25
none
-
.font-m
is400 26px/1.25
none
-
.font-l
is600 32px/1.25
none
-
.font-xl
is600 42px/1
none
.font-os
-
.font-os
Recommended. Equals.family-os
Unormal normal 400
.family-inherit
.family-os
font-weight
.weight-inherit
.weight-light
-
.weight-normal
legacy alias:.unbold
-
.weight-semibold
legacy alias:.semibold
-
.weight-bold
legacy alias:.bold
.font-collapse
- Collapse whitespace or hide text in a11y technique
-
.font-collapse
=.size-collapse
U.line-collapse
font-size
.size-inherit
.size-14px
.size-16px
.size-20px
.size-26px
.size-32px
.size-42px
-
.size-body
at risk -
.size-caption
at risk
line-height
-
.line-initial
fornormal
initial -
.line-inherit
forinherit
-
.line-single
is1
for use on headings or alignments -
.line-subcompact
is1.125
for use on headings -
.line-compact
is1.25
for use on headings -
.line-passing
is1.5
for text. Passes WCAG guidelines -
.line-double
is2
for special cases
text-transform
Case classes transform the entire element while letter classes only transform the ::first-letter
such that you can compose as needed like "case-lower letter-upper"
for sentence case.
-
.case-none
CSS is composable -
.case-lower
css is composable -
.case-upper
CSS IS COMPOSABLE -
.case-proper
CSS Is Composable -
.letter-lower
cSS is composable -
.letter-upper
CSS is composable -
.case-lower.letter-upper
Css is composable -
.case-upper.letter-lower
cSS IS COMPOSABLE
text-decoration
-
.underline-none
removes underline. You must provide alternative visual affordance. -
.underline-focus
adds underline on:focus
-
.underline-hover
adds underline on:hover
-
.underline
adds underline to all states
cursor
-
.pointer
setcursor
topointer
unless disabled
pointer-events
.events-none { pointer-events: none }
.events-auto { pointer-events: auto }
appearance
-
.appearance-none
sets vendor appearance tonone
for custom styling
resize
.resize-none
.resize-both
transform
-
.-tx100
fortranslateX(-100%)
-
.-ty100
fortranslateY(-100%)
-
.tx0
fortranslateX(0)
-
.ty0
fortranslateY(0)
-
.tx100
fortranslateX(100%)
-
.ty100
fortranslateY(100%)
animation
-
.anim-initial
resetsanimation
to itsinitial
values -
.anim-reverse
reverses animation -
.anim-seed
usesbackwards
fill mode -
.anim-stay
usesforwards
fill mode -
.anim-fill
usesboth
fill mode -
.anim-paused
pauses animation -
.anim-infinite
animates for infinite iterations -
.keyspeeds-spin
duration for spinner iterating -
.keyframes-spin
rotate from0deg
to360deg
iterating
Presets
Presets provide partials for common needs. Presets load early such that other classes may override them.
-
.preset-box
box-model base -
.preset-input
input base -
.preset-textarea
textarea base -
.preset-button
button base
JavaScript API
We are developing a JavaScript API to help component developers reliably compose classes.
npm install @plangrid/structure
const structure = require("@plangrid/structure");
structure
is a frozen cader
instance.
structure.fuse("FontXL") // "family-os weight-semibold size-42px line-single"
structure.fuse("Tap") // "family-os preset-button fill-current pointer"
structure.fuse("Tap FontXL") // Unique fusion of both
structure.bond("FontXL another") // Unique bonding of saved atom(s) and unsaved atom(s)
structure.bond("FontXL m0 mb1") // "family-os weight-semibold size-42px line-single m0 mb1"
-
.bond
permits mixing atoms with external classes whereas.fuse
is strictly atoms that have been saved - Call
structure.help()
for help -
.clone
is available for feature work
const feature = structure.clone() // new instance contains saved structure atoms
feature.save({/* ... */}) // can save more atoms if unique from structure atoms
Available atoms
Font atoms
structure.bond("FontC") // "font-os font-c"
structure.bond("FontB") // "font-os font-b"
structure.bond("FontXXS") // "font-os font-xxs"
structure.bond("FontXS") // "font-os font-xs"
structure.bond("FontS") // "font-os font-s"
structure.bond("FontM") // "font-os font-m"
structure.bond("FontL") // "font-os font-l"
structure.bond("FontXL") // "font-os font-xl"
Border atoms
structure.bond("ShelfMeld") // "sharp-shelf meld-shelf"
structure.bond("ShelfWeld") // "sharp-shelf weld-shelf"
structure.bond("StackMeld") // "sharp-stack meld-stack"
structure.bond("StackWeld") // "sharp-stack weld-stack"
Overflow atoms
structure.bond("TruncateBox") // "overflow-hidden overflow-dots ws-nowrap preset-box"
structure.bond("TruncateDIY") // "overflow-hidden overflow-dots ws-nowrap"
structure.bond("TruncateDIY width-fit") // max-width: 100%
structure.bond("PaneX") // "preset-box oy-hidden ox-auto"
structure.bond("PaneY") // "preset-box ox-hidden oy-auto"
structure.bond("PaneX PaneY") // both auto
- See preset.css to see what
.preset-box
does -
Pane
is meant to provide our standard scrolling behavior. TBD if we will standardize onauto
orscroll
Shadow atoms
structure.bond("FlatControl") // "shadow-ring"
structure.bond("RaiseControl") // "shadow-raised shadow-ring"
structure.bond("RaiseStatic") // "shadow-raised"
Control atoms
-
HF
= heavy frame -
LF
= light frame -
WIP
= work in progress
structure.bond("UnderNone") // "underline-none"
structure.bond("UnderSome") // "underline-none underline-hover"
structure.bond("UnderAll") // "underline"
structure.bond("Ask") // structure.bond("FontB line-single preset-box block-table")
structure.bond("Cbox") // "font-os preset-button cbox"
structure.bond("Rdio") // "font-os preset-button rdio"
structure.bond("Field") // "font-os preset-box border-none"
structure.bond("Tactile") // "font-os preset-box block-table"
structure.bond("InputLF") // "font-os preset-input round-medium border"
structure.bond("InputHF") // structure.bond("InputLF frame-basic")
structure.bond("OpdownWIP") // structure.bond("PaneY round-medium RaiseControl")
structure.bond("OptionLF") // "overflow-hidden overflow-dots ws-nowrap preset-box font-os block"
structure.bond("OptionHF") // structure.bond("OptionLF font-b p1")
structure.bond("TapLF") // "font-os preset-button"
structure.bond("TapHF") // "font-os preset-button pointer"
structure.bond("TextareaLF") // "font-os preset-textarea round-medium border"
structure.bond("TextareaHF") // structure.bond("TextareaLF frame-basic")
structure.bond("PutLF") // "font-os preset-input round-medium border sharp-shelf weld-shelf"
structure.bond("PutHF") // structure.bond("PutLF frame-basic")
Unstable atoms
structure.bond("Checkbox") // "font-os preset-button cbox shadow-raised shadow-ring tone-check"
structure.bond("Radio") // "font-os preset-button rdio shadow-raised shadow-ring tone-check"
Deprecated atoms
structure.bond("Tap") // => structure.bond("TapLF")
structure.bond("Input") // => structure.bond("InputHF RaiseControl")
structure.bond("Textarea") // => structure.bond("TextareaHF RaiseControl")
structure.bond("Input:validate") // => structure.bond("InputHF RaiseControl tone-validate")
structure.bond("Input:validity") // => structure.bond("InputHF RaiseControl tone-validity")
structure.bond("Input:valid") // => structure.bond("InputHF RaiseControl tone-valid")
structure.bond("Input:invalid") // => structure.bond("InputHF RaiseControl tone-invalid")
structure.bond("Textarea:validate") // => structure.bond("TextareaHF RaiseControl tone-validate")
structure.bond("Textarea:validity") // => structure.bond("TextareaHF RaiseControl tone-validity")
structure.bond("Textarea:valid") // => structure.bond("TextareaHF RaiseControl tone-valid")
structure.bond("Textarea:invalid") // => structure.bond("TextareaHF RaiseControl tone-invalid")
structure.bond("Button:secondary")
structure.bond("Button:primary")
structure.bond("Button:additive")
structure.bond("Button:destructive")
structure.bond("Secondary")
structure.bond("Primary")
structure.bond("Additive")
structure.bond("Destructive")
structure.bond("Button:link")
structure.bond("Button:icon")
Questions?
Ask in our #css slack channel :)
Developer commands
npm install
npm start
npm test