@plangrid/structure v0.37.0
structure
npm install @plangrid/structuremain.cssis 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-itemsalign-contentalign-selfjustify-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-staticfor use like"relative focus-static"to sink on focus.focus-relativefor 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
.borderDeprecated. Favorborder-1px border-solid.border-topDeprecated. Favorborder-1px bt-solid.border-leftDeprecated. Favorborder-1px bl-solid.border-rightDeprecated. Favorborder-1px br-solid.border-bottomDeprecated. Favorborder-1px bb-solid.border-1pxis our standardborder-widthfor 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
.roundedDeprecated. Favorround-medium.rounded-stackDeprecated. Favorround-medium sharp-stack.rounded-shelfDeprecated. Favorround-medium sharp-shelf.round-smallfor2pxcorners. Use on pills.round-mediumfor3pxcorners. Use on buttons, cards....round-largefor12pxcorners. Use on modals.round-circlefor50%corners.sharp-topzero top corners.sharp-leftzero left corners.sharp-rightzero right corners.sharp-bottomzero bottom corners.sharp-shelfzero interior shelf corners.sharp-stackzero 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-visibledefault (element box is visible).vis-hiddeninvisible and inaccessible but retains layout.vis-collapseinvisible and inaccessible but retains flex strut or table layout with careful use
overflow
.overflow-visibleor per axis.ox-visible.oy-visible.overflow-hiddenor per axis.ox-hidden.oy-hidden.overflow-scrollor per axis.ox-scroll.oy-scroll.overflow-autoor per axis.ox-autooy-auto.overflow-dotssetstext-overflowtoellipsis.wrap-normalsetsoverflow-wraptonormal.wrap-wordsetsoverflow-wraptobreak-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-discsets type todisc(initial).list-circlesets type tocircle.list-outsidesets position tooutside(initial).list-insidesets position toinside.list-nonesets 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-baselinedefault.align-top.align-middle.align-bottom.align-sub.align-super.align-ascentfortext-top.align-descentfortext-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-cis400 12px/1.25none.font-bis400 14px/1.5none.font-xxsis400 12px/1.25uppercase.font-xsis600 16px/1.5none.font-sis400 20px/1.25none.font-mis400 26px/1.25none.font-lis600 32px/1.25none.font-xlis600 42px/1none
.font-os
.font-osRecommended. Equals.family-osUnormal normal 400.family-inherit.family-os
font-weight
.weight-inherit.weight-light.weight-normallegacy alias:.unbold.weight-semiboldlegacy alias:.semibold.weight-boldlegacy alias:.bold
.font-collapse
- Collapse whitespace or hide text in a11y technique
.font-collapse=.size-collapseU.line-collapse
font-size
.size-inherit.size-14px.size-16px.size-20px.size-26px.size-32px.size-42px.size-bodyat risk.size-captionat risk
line-height
.line-initialfornormalinitial.line-inheritforinherit.line-singleis1for use on headings or alignments.line-subcompactis1.125for use on headings.line-compactis1.25for use on headings.line-passingis1.5for text. Passes WCAG guidelines.line-doubleis2for 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-noneCSS is composable.case-lowercss is composable.case-upperCSS IS COMPOSABLE.case-properCSS Is Composable.letter-lowercSS is composable.letter-upperCSS is composable.case-lower.letter-upperCss is composable.case-upper.letter-lowercSS IS COMPOSABLE
text-decoration
.underline-noneremoves underline. You must provide alternative visual affordance..underline-focusadds underline on:focus.underline-hoveradds underline on:hover.underlineadds underline to all states
cursor
.pointersetcursortopointerunless disabled
pointer-events
.events-none { pointer-events: none }
.events-auto { pointer-events: auto }appearance
.appearance-nonesets vendor appearance tononefor custom styling
resize
.resize-none.resize-both
transform
.-tx100fortranslateX(-100%).-ty100fortranslateY(-100%).tx0fortranslateX(0).ty0fortranslateY(0).tx100fortranslateX(100%).ty100fortranslateY(100%)
animation
.anim-initialresetsanimationto itsinitialvalues.anim-reversereverses animation.anim-seedusesbackwardsfill mode.anim-stayusesforwardsfill mode.anim-fillusesbothfill mode.anim-pausedpauses animation.anim-infiniteanimates for infinite iterations.keyspeeds-spinduration for spinner iterating.keyframes-spinrotate from0degto360degiterating
Presets
Presets provide partials for common needs. Presets load early such that other classes may override them.
.preset-boxbox-model base.preset-inputinput base.preset-textareatextarea base.preset-buttonbutton base
JavaScript API
We are developing a JavaScript API to help component developers reliably compose classes.
npm install @plangrid/structureconst 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".bondpermits mixing atoms with external classes whereas.fuseis strictly atoms that have been saved- Call
structure.help()for help .cloneis available for feature work
const feature = structure.clone() // new instance contains saved structure atoms
feature.save({/* ... */}) // can save more atoms if unique from structure atomsAvailable 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-boxdoes Paneis meant to provide our standard scrolling behavior. TBD if we will standardize onautoorscroll
Shadow atoms
structure.bond("FlatControl") // "shadow-ring"
structure.bond("RaiseControl") // "shadow-raised shadow-ring"
structure.bond("RaiseStatic") // "shadow-raised"Control atoms
HF= heavy frameLF= light frameWIP= 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