UNPKG

@plangrid/structure

Version:
528 lines (415 loc) 19.3 kB
# structure - [`npm install @plangrid/structure`](https://www.npmjs.com/package/@plangrid/structure) - [`main.css`](main.css) is the production bundle - [unpkg](https://unpkg.com/@plangrid/structure/) for [codepen](https://codepen.io/ryanve/pen/gRamvZ) - [`CONTRIBUTING.md`](CONTRIBUTING.md) - [JavaScript API](#javascript-api) ## Usage - Favor flexbox for layout over other layout techniques - [Flexbox classes](modules/flexbox.css) use pure [flex properties](https://www.w3.org/TR/css-flexbox-1/) to afford layouts in any direction or [alignment](modules/alignment.css) - Be aware of [flexbugs](https://github.com/philipwalton/flexbugs#flexbugs) and especially test complex layouts for browser differences ### `flex` [balanced grid](https://codepen.io/ryanve/pen/mmgjXE) ```html <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](https://codepen.io/ryanve/pen/JNzPMw) ```html <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](https://codepen.io/ryanve/pen/BdJgzp) ```html <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](https://codepen.io/ryanve/pen/RVOYoZ) ```html <div class="flex items-center justify-center"> <p>I'm centered :) </div> ``` ### [`alignment`](modules/alignment.css) - [Our alignment classes](modules/alignment.css) are useful for aligning flex items - Properties include [`align-items`](https://developer.mozilla.org/en-US/docs/Web/CSS/align-items) [`align-content`](https://developer.mozilla.org/en-US/docs/Web/CSS/align-content) [`align-self`](https://developer.mozilla.org/en-US/docs/Web/CSS/align-self) [`justify-content`](https://developer.mozilla.org/en-US/docs/Web/CSS/justify-content) - Values include [alignment values](https://www.w3.org/TR/css-align-3/#alignment-values) that are supportable by our browser coverage - W3C categorizes values as [positional](https://www.w3.org/TR/css-align-3/#positional-values) | [baseline](https://www.w3.org/TR/css-align-3/#baseline-values) | [distribution](https://www.w3.org/TR/css-align-3/#distribution-values) ### [`spacing`](https://github.com/ryanve/spacing/tree/v0.3.0#classes) ```html <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](https://github.com/plangrid/structure/pull/44): [`[data-spacing]`](https://github.com/ryanve/spacing/tree/v0.2.1#data-spacing) ```jsx <Component data-spacing="mt0 mb2"> ``` ### [`position`](https://codepen.io/ryanve/pen/PmgBLK) - `.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` ```html <div class="relative"> <div class="absolute top-0 left-0 right-0 bottom-0">I fill my container</div> </div> ``` ### [`border`](modules/border.css) - `.border` **Deprecated.** Favor `border-1px border-solid` - `.border-top` **Deprecated.** Favor `border-1px bt-solid` - `.border-left` **Deprecated.** Favor `border-1px bl-solid` - `.border-right` **Deprecated.** Favor `border-1px br-solid` - `.border-bottom` **Deprecated.** Favor `border-1px bb-solid` - `.border-1px` is our standard `border-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`](https://plangrid.github.io/structure/#corners) 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.** Favor `round-medium` - `.rounded-stack` **Deprecated.** Favor `round-medium sharp-stack` - `.rounded-shelf` **Deprecated.** Favor `round-medium sharp-shelf` - `.round-small` for `2px` corners. Use on pills - `.round-medium` for `3px` corners. Use on buttons, cards... - `.round-large` for `12px` corners. Use on modals - `.round-circle` for `50%` 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 ```html <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> ``` ```html <div class="width-em height-em round-circle">circle</div> ``` ### [`border-width`](https://codepen.io/ryanve/pen/jYygaX) 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)` ```html <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> ``` ```html <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`](https://codepen.io/ryanve/pen/aWxjpX) ```html <label class="block"> <input class="inline-block mr1" type="checkbox" checked> Use functional CSS </label> ``` ### [`visibility`](https://developer.mozilla.org/en-US/docs/Web/CSS/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](https://drafts.csswg.org/css-flexbox-1/#visibility-collapse) or [table layout](https://drafts.csswg.org/css-tables-3/#visibility-collapse-rendering) with [careful use](https://developer.mozilla.org/en-US/docs/Web/CSS/visibility#Browser_compatibility) ### [`overflow`](modules/overflow.css) - `.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` sets `text-overflow` to `ellipsis` - `.wrap-normal` sets `overflow-wrap` to `normal` - `.wrap-word` sets `overflow-wrap` to `break-word` ```html <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`](https://developer.mozilla.org/en-US/docs/Web/CSS/white-space) - `.ws-normal` - `.ws-nowrap` - `.ws-pre` - `.ws-pre-wrap` - `.ws-pre-line` ### [`sizing`](modules/sizing.css) ```html <div class="max-viewport min-zero width-all height-all"> example </div> ``` ### [`float`](https://developer.mozilla.org/en-US/docs/Web/CSS/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](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Block_formatting_context). ### [`list-style`](https://developer.mozilla.org/en-US/docs/Web/CSS/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](https://developer.mozilla.org/en-US/docs/Web/CSS/list-style-position). - `.list-disc` sets type to `disc` (initial) - `.list-circle` sets type to `circle` - `.list-outside` sets position to `outside` (initial) - `.list-inside` sets position to `inside` - `.list-none` sets style to `none` ### [`text-align`](https://developer.mozilla.org/en-US/docs/Web/CSS/text-align) - `.text-left` - `.text-right` - `.text-center` ### [`vertical-align`](https://developer.mozilla.org/en-US/docs/Web/CSS/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` for `text-top` - `.align-descent` for `text-bottom` ### [`font`](modules/font.css) - Display fonts are named in t-shirt sizes. [See demo](https://plangrid.github.io/structure/#fonts) and round to the nearest fit :) - Components may access via [`import structure from "@plangrid/structure"`](#javascript-api) ```js 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` is `400 12px/1.25` `none` - `.font-b` is `400 14px/1.5` `none` - `.font-xxs` is `400 12px/1.25` `uppercase` - `.font-xs` is `600 16px/1.5` `none` - `.font-s` is `400 20px/1.25` `none` - `.font-m` is `400 26px/1.25` `none` - `.font-l` is `600 32px/1.25` `none` - `.font-xl` is `600 42px/1` `none` #### `.font-os` - `.font-os` Recommended. Equals `.family-os` U `normal 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` for `normal` initial - `.line-inherit` for `inherit` - `.line-single` is `1` for use on headings or alignments - `.line-subcompact` is `1.125` for use on headings - `.line-compact` is `1.25` for use on headings - `.line-passing` is `1.5` for text. [Passes WCAG guidelines](https://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast-visual-presentation.html) - `.line-double` is `2` for special cases ### [`text-transform`](https://developer.mozilla.org/en-US/docs/Web/CSS/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`](https://developer.mozilla.org/en-US/docs/Web/CSS/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`](modules/cursor.css) - `.pointer` set `cursor` to `pointer` unless disabled ### [`pointer-events`](modules/pointer-events.css) ```css .events-none { pointer-events: none } .events-auto { pointer-events: auto } ``` ### [`appearance`](modules/vendor.css) - `.appearance-none` sets vendor appearance to `none` for custom styling ### [`resize`](modules/resize.css) - `.resize-none` - `.resize-both` ### [`transform`](modules/transform.css) - `.-tx100` for `translateX(-100%)` - `.-ty100` for `translateY(-100%)` - `.tx0` for `translateX(0)` - `.ty0` for `translateY(0)` - `.tx100` for `translateX(100%)` - `.ty100` for `translateY(100%)` ### [`animation`](modules/animation.css) - `.anim-initial` resets `animation` to its `initial` values - `.anim-reverse` reverses animation - `.anim-seed` uses `backwards` fill mode - `.anim-stay` uses `forwards` fill mode - `.anim-fill` uses `both` fill mode - `.anim-paused` pauses animation - `.anim-infinite` animates for infinite iterations - `.keyspeeds-spin` duration for spinner **iterating** - `.keyframes-spin` rotate from `0deg` to `360deg` **iterating** ### [Presets](preset.css) 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 ``` ```js const structure = require("@plangrid/structure"); ``` [`structure`](structure.js) is a frozen [`cader`](https://github.com/ryanve/cader/tree/v0.7.0#cader) instance. ```js 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 ```js const feature = structure.clone() // new instance contains saved structure atoms feature.save({/* ... */}) // can save more atoms if unique from structure atoms ``` ### Available atoms #### [Font](#font) atoms ```js 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](#border) atoms ```js 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](#overflow) atoms ```js 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](preset.css) to see what `.preset-box` does - `Pane` is meant to provide our standard scrolling behavior. TBD if we will standardize on `auto` or `scroll` #### Shadow atoms ```js 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 ```js 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 ```js 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 ```js 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 <b>#css</b> slack channel :) ## Developer commands ``` npm install npm start npm test ```