When it comes to adding styles to Next.js sites, there are many options, given its built-in CSS support.

Stackbit provides two additional features that you can use to pass on the flexibility of styling components and pages to your content editors. The first is a control panel at the component level, also referred to as user-controlled styles.

In this lesson, we'll add the option for editors to set padding and margin on the new post feed component that you've added to the home page.

In this lesson:

  • Styling with Next.js
  • User-controlled styles
  • Mapping content to CSS classes

Add Style Controls to Post Feed Model

As usual, we begin by working with a content model. In this case, we'll add a field called styles of type style (note the naming difference) to the post feed component.

# .stackbit/models/PostFeed.yaml

# ...
fields:
  # ...
  - type: style
    name: styles
    styles:
      self:
        padding: ['y0', 'y32']
      heading:
        margin: ['b0', 'b32']

These settings are going to enable the editor to set a top and bottom padding on the post feed containing element, and also the bottom margin on the heading. To keep things simple, we're only showing two options here - 0px or 32px.

There are a number of supported styling options. Learn more about component styles.

Set Component Styles

You can see this feature come to life immediately. There should now be a teardrop icon on the section heading and the container. Go ahead and set the heading and container to 32px value.

Component style control panel

Notice that this changes the values of a nested style field on the page containing this element. After adjusting the values, open content/pages/index.md (home page source file) to see the new content.

# content/pages/index.md

# ...
- heading: Post Feed Title
  subheading: Subhbeading goes here ...
  type: PostFeed
  styles:
    self:
      padding:
        top: '32'
        bottom: '32'
    heading:
      margin:
        bottom: '16'

Build Content-Mapping Utility

Enabling this feature in the editor is super quick. The trickier part is mapping these values in this deeply-nested object to classes that you can use to style components.

There are three steps here:

  1. Build the mapping utility
  2. Map content to classes on the component
  3. Add the CSS style rules

1. Building Mapping Utility

For this particular case, we only have two rules to account for. Here's an example of how you might implement the mapping functionality in a utils/style-mapper.js file:

// utils/style-mapper.js

const directionMap = {
  top: 't',
  right: 'r',
  bottom: 'b',
  left: 'l'
}

function mapSpacingStyles(values, prefix) {
  return Object.entries(values).map(([dir, val]) => `${prefix}${directionMap[dir]}-${val}`)
}

const styleMap = {
  padding: (values) => mapSpacingStyles(values, 'p'),
  margin: (values) => mapSpacingStyles(values, 'm')
}

export function mapStyles(styles) {
  return Object.entries(styles)
    .flatMap(([style, value]) => styleMap[style](value))
    .join(' ')
}

This is using a formula that builds Tailwind-like utility classes. So, for example, padding.bottom: 32px maps to pb-32.

Applying to Your Site

When it comes to applying this approach to your site, how exactly you implement this will depend on the scenarios that you want to account for with your editors.

Official Stackbit themes use Tailwind and provide their own mapping utility, which may help you determine the best course of action for your project.

2. Mapping Content to Classes

After the mapper is in place, you can use it to map the styles from your content to classes in your post card component.

// components/PostFeed.jsx

import { mapStyles } from '../utils/style-mapper'

export const PostFeed = (props) => {
  return (
    <div data-sb-field-path={props['data-sb-field-path']} className={mapStyles(props.styles.self)}>
      <h2 data-sb-field-path=".heading" className={mapStyles(props.styles.heading)}>
        {props.heading}
      </h2>
      {/* ... */}
    </div>
  )
}

3. Adding CSS Style Rules

The last piece of the puzzle is the styles themselves. We're not using a CSS framework (yet), so we can manually add these classes to styles/styles.css.

/* styles/styles.css */

.pt-0 {
  padding-top: 0px;
}

.pb-0 {
  padding-bottom: 0px;
}

.pt-32 {
  padding-top: 32px;
}

.pb-32 {
  padding-bottom: 32px;
}

.mb-0 {
  margin-bottom: 0px;
}

.mb-32 {
  margin-bottom: 32px;
}

After you've made these changes you should see them take effect. If they don't right away, give your browser a refresh.

Post feed component with styles