Polythene CSS
March 22, 2020 ยท View on GitHub
Basic principles
Polythene styles can be included in 2 ways:
- Using CSS-in-JS
- Importing/linking CSS files
Which option you choose may depend on how (and if) you want to use theming - more on that below.
Getting started
With either option, polythene-css should be installed - see Getting started with Mithril or Getting started with React.
Using CSS-in-JS
Using CSS-in-JS has minimal setup costs and gives the possibility to add themed component styles on the fly.
Usage
Importing polythene-css activates CSS-in-JS:
import "polythene-css"
Theming options for CSS-in-JS
Because styles are generated by JavaScript, no CSS-build step is required. Adding a component theme is as simple as: addStyle(".themed-component", { vars }). For example:
IconCSS.addStyle(".my-icon", {
size_regular: 44,
color_light: "purple"
})
Read more at Styling with variables.
Under the hood
Component styles are automatically added to <head> using j2c.
Using CSS files
Choose this:
- If you don't need to create themed component styles on the fly
- or if you are already using a bundler that grabs and bundles all CSS files.
- or if you don't want to be reliant on the client rendering, for example when doing server-side rendering or when using a static site generator.
Usage
Package polythene-css contains all component CSS files. Its existence in node_modules makes it possible to import CSS files.
Most bundlers have options for importing CSS files. Frequently used with Webpack is mini-css-extract-plugin.
Importing all CSS:
import "polythene-css/dist/polythene.css" // Component CSS
import "polythene-css/dist/polythene-typography.css" // Default Material Design styles including Roboto font
Alternatively, import a single component's CSS:
import "polythene-css/dist/polythene-button.css"
Theming options for CSS files
Theming options are more limited than using CSS-in-JS as styles will not be added on the fly. But it is still possible to use the same tools as CSS-in-JS, only with an extra build step that results in a CSS file. This step can be automated of course.
Creating CSS is very similar to CSS-in-JS, but instead of addStyle you call getStyle to fetch the styles before writing them to a file.
writej2c is provided by library write-j2c - see write-j2c documentation.
For example, to create a CSS file that contains themed CSS for Card and Button, you could write:
// ./scripts/writeThemeCSS.js
const { writej2c } = require("write-j2c")
const { CardCSS, ButtonCSS } = require("polythene-css")
const styles = [
CardCSS.getStyle(".themed-card", {
color_dark_main_background: "#B89E58",
color_dark_title_text: "#fff",
color_dark_subtitle_text: "#fff"
}),
ButtonCSS.getStyle(".themed-button", {
color_light_text: "red"
})
]
writej2c({
styles,
path: "./dist/css/theme.css",
autoPrefix: true,
gzip: true
})
... and in your package.json build script:
"build": "node ./scripts/writeThemeCSS.js && webpack --config scripts/webpack.config.prod.js"
Alternative approach
You could always resort to create handwritten CSS. Although this does not require a build step, this may not be future proof. When a component structure would change later on, your custom CSS may no longer work.
Extras
Supporting styles
Supporting styles (typography and Roboto web font styles) are optional.
Using CSS-in-JS
import { addTypography } from "polythene-css"
addTypography()
See also:
Using CSS files
import "polythene-css/dist/polythene-typography.css"
Roboto font
Roboto using CSS-in-JS
The Material Design Roboto font is automatically loaded when addTypography is used, but it can also be loaded independent of typography styles:
import { addRoboto } from "polythene-css"
addRoboto()
The Material Design Roboto font is loaded from Google Fonts using webfontloader.
The benefit of using this approach is that when the font is loaded, styles are added to the html tag, giving simple hooks to change styles based on the loaded state.
For example, to prevent the Flash of Unstyled Text (FOUT), add these styles:
body {
opacity: 0
}
html.wf-active body {
opacity: 1
}
Or with CSS-in-JS using styler:
import { styler } from "polythene-core-css"
const foutStyles = [{
"body": {
opacity: 0
},
"html.wf-active body": {
opacity: 1
}
}]
styler.add("fout", foutStyles)
Roboto using CSS files
Roboto will be loaded automatically when polythene-typography is imported:
import "polythene-css/dist/polythene-typography.css"
Layout classes
Package polythene-css also includes helper classes that are useful to quickly add layout styles to hyperscript / JSX (see the complete list of layout classes below).
Mithril example
m(".layout.vertical", "Vertical content")
React JSX example
<div className="layout vertical">Vertical content</div>
Layout classes using CSS-in-JS
import { addLayoutStyles } from "polythene-css"
addLayoutStyles()
Layout classes using CSS files
import "polythene-css/dist/polythene-layout-styles.css"
List of layout classes
Common helper classes:
.pe-block
.pe-inline-block
.pe-hidden
.pe-relative
.pe-absolute
.pe-fit
.pe-fullbleed
Flex classes:
/* flex */
.flex
.flex.auto
.flex.auto-vertical
.flex.none
.flex.one
.flex.two
.flex.three
.flex.four
.flex.five
.flex.six
.flex.seven
.flex.eight
.flex.nine
.flex.ten
.flex.eleven
.flex.twelve
/* layout */
.layout
.layout.horizontal
.layout.horizontal.inline
.layout.vertical.inline
.layout.horizontal
.layout.horizontal.reverse
.layout.vertical
.layout.vertical.reverse
.layout.wrap
.layout.wrap.reverse
/* alignment in cross axis */
.layout.start
.layout.center,
.layout.center-center
.layout.end
/* alignment in main axis */
.layout.start-justified
.layout.center-justified
.layout.center-center
.layout.end-justified
.layout.around-justified
.layout.justified
/* self alignment */
.self-start
.self-center
.self-end
.self-stretch