Styling Components

All of Maker UI's components support special breakpoints and css props. These props let you specify media query breakpoints as an array of values that correspond with CSS rules.

Here's how the syntax looks in action:

1/* Set breakpoints to 768px and 960px */
2
3<Div
4 breakpoints={[768, 960]}
5 css={{
6 color: ['blue', 'red', 'purple'],
7 }}>
8 Hello world
9</Div>

Maker UI stacks your CSS array values as min-width media queries. In the example above, the div's base color would be blue. At min-width(768px) the div's color would turn red, and finally at min-width(960px) the div's color would become purple.

The first index of your CSS attribute array will always serve as the base style for your component.

Here's another example:

1/* When the browser's width is >= 1000px, this div will have
2 a height of `auto` and a background of `#f9f9f9` */
3
4<Div
5 breakpoints={[1000]}
6 css={{
7 height: [100, 'auto'],
8 background: ['#fff', '#f9f9f9'],
9 color: '#36748d',
10 }}>
11 Another div
12</Div>

Composing Styles#

The CSS prop will accept any officially adopted CSS attribute as both a single value or an array of values. If you can write it in a stylesheet, you can use it with the CSS prop.

You can also use custom functions or spread operators to create dynamic style rules. If any rule is undefined at run or buildtime, the parser will ignore it.

TypeScript#

For TypeScript users, some text editors that support auto-complete or intellisense may display and help you select valid CSS values as you declare styles.

If you ever need to use a function that returns a style object, just cast your function as an object:

1function getDynamicStyles() {
2 return {
3 height: isMobile ? 50 : 100,
4 ...
5 }
6}
7
8/* Type casting an `object` will eliminate TypeScript errors */
9
10<Div
11 breakpoints={[960]}
12 css={{
13 color: 'red',
14 ...(getDynamicStyles())
15 }}>
16 Hello world
17</Div>

Nesting Selectors#

You can use the CSS prop just like a Sass stylesheet-- nest styles for as many child elements as you'd like. You would simply use the name of the HTML tag or a CSS selector as the key for a child element's style declaration:

1/* Style nested elements by specifying the name of the HTML element
2 or by using an ID or className selector */
3
4<Div
5 css={{
6 // className selector
7 '.red': {
8 color: 'red',
9 },
10 // <section> tag selector
11 section: {
12 background: '#e6e6e6',
13 color: 'blue',
14 // ID selector
15 '#orange': {
16 color: 'orange',
17 },
18 },
19 }}>
20 <p className="red">Red text</p>
21 <section>
22 <p>Blue text</p>
23 <p id="orange">Orange text</p>
24 </section>
25</Div>

Pseudo Selectors#

Declare styles for pseudo elements (:before and :after), state (:hover, :focus, :active, etc.), or chained classes by prefacing the rule with an ampersand & symbol:

1<Button
2 className={active ? 'active' : undefined}
3 onClick={() => setActive(!active)}
4 css={{
5 background: '#333',
6 '&:hover': {
7 background: '#000',
8 },
9 '&.active': {
10 background: '#d6d6d6',
11 },
12 }}>
13 Hover over me
14</Button>

When to Inline vs Import#

While prototyping, it's often easiest to bake styles directly into your JSX. This strategy also works really well when you can keep your files small with a modular component architecture.

However, as your component grows in complexity, you might have a hard time identifying business logic if the JSX becomes bloated with styles. You can clean up your files by definining several styles in one place as a separate object.

Scoped Styles#

With this approach, you add a nested style declaration to a parent component or outer container. All child element styles will be derived from the parent's css prop. Any responsive arrays in your style object will abide by global breakpoints or the locally scoped breakpoints prop.

This pattern encourages you to rely more on CSS selectors and to write cleaner JSX in your React components.

1import { Div } from 'maker-ui'
2
3const styles = {
4 background: '#fff',
5 padding: '10px 20px',
6 '.card': {
7 color: 'tomato',
8 border: '1px solid gainsboro',
9 margin: [30, 50],
10 }
11 '.card-title': {
12 fontWeight: 700,
13 fontSize: ['1.3em', '1.5em']
14 },
15 p: {
16 color: '#333'
17 }
18}
19
20/* The styles object is applied to the root <Div /> and all nested
21elements are locally scoped */
22
23const TestComponent = () => (
24 <Div css={styles}>
25 <div className="card">
26 <h2 className="card-title">Title</h2>
27 <p>paragraph one</p>
28 <p>paragraph two</p>
29 </div>
30 </Div>
31)

Module Styles#

This approach is commonly used in React applications that leverage CSS Modules. You can use a dictionary of style declarations for each Maker UI primitive or component:

1import { Div, H2 } from 'maker-ui'
2
3const styles = {
4 root: {
5 background: '#fff',
6 padding: '10px 20px',
7 },
8 card: {
9 color: 'tomato',
10 border: '1px solid gainsboro',
11 margin: [30, 50],
12 },
13 title: {
14 fontWeight: 700,
15 fontSize: [20, 28],
16 },
17}
18
19/* NOTE - You must use a Maker UI component or the JSX pragma
20to access the CSS prop */
21
22const TestComponent = () => (
23 <Div css={styles.root}>
24 <Div css={styles.card}>
25 <H2 css={styles.title}>Title</H2>
26 </Div>
27 </Div>
28)

_css Prop#

Several Maker UI components render a container element. This is useful for applying a maxWidth rule to the component's inner contents or adding a CSS display of flex or grid to the container.

If you ever need to style a root container element, you can use the _css prop.

To see if a component has a _css prop, check out its respective documentation page.

Usage with Layout API#

You may never need to add a breakpoints prop to any of your components if you are using the Layout API. The MakerUIOptions configuration lets you set a global breakpoints array so that all nested components obey the same media queries by default.

When you need a custom media query that is different from the array you specified in your MakerUIOptions, the breakpoints prop will always take precedence.

Color Modes and CSS Variables#

Unlike other CSS-in-JS libraries, Maker UI relies on CSS variables instead of React Context for theming.

MakerUIOptions give you an easy way to define custom variables and themeable color palettes that you can use in your application. Access these values with normal CSS variable syntax:

1<Div css={{ color: 'var(--color-primary)' }}>Hello world</Div>
Contents