Skip to content

Global styles and layouts

Mason Medeiros edited this page Jul 29, 2017 · 10 revisions

This page will answer how to set global styles like

  • Your page's background color
  • Your global font size / font family configuration
  • CSS resets, such as * { box-sizing: border-box; margin: 0; padding: 0 }
  • Any other styles you might want on <body> or <html>

The easiest way to accomplish it is by using the <style jsx global> tag on a component, specifically with <Head>. For example, in pages/index.js:

import Head from 'next/head'
export default () => (
  <div>
    <Head>
      <meta name="viewport" content="width=device-width, initial-scale=1" />
      <meta charSet="utf-8" />
    </Head>
    <style jsx global>{`
      body { 
        background: #000;
        font: 11px menlo;
        color: #fff;
      }
    `}</style>
  </div>
)

When the page is rendered, a <style> element will be placed in <head>.

Now, how do you do this for every page? In Next.js there's no concept of "global layout". Every page in your Next.js project is complete and self-sufficient.

If you've used WordPress in the past, it's similar to how every core template page has to invoke get_header and get_footer.

So, the easiest solution is to have your pages invoke something like a custom header or footer.

Let's say that what you defined above as pages/index.js now lives in components/meta.js, since that is all it currently contains. You've also created a footer in components/footer.js to use across all your pages. Now, you use both in pages/index.js:

import Meta from '../components/meta'
import Footer from '../components/footer'
export default () => (
  <div>
    <Meta />
    <p>hi there</p>
    <Footer />
  </div>
)

For this example, your directory structure would look like:

components/
  meta.js
  footer.js
pages/
  index.js

Notice that components/ is completely arbitrary, but I happen to like that structure. Then components/meta.js can introduce the <Head> with <style jsx global>, so that it can be applied to every page.

It's also possible to create "master layouts" that embed these components on your behalf, by leveraging React's children property.

For example, you can introduce layouts/main.js:

components/
  meta.js
  footer.js
pages/
  index.js
layouts/
  main.js

and the component can act as a wrapper:

import Meta from '../components/meta'
import Footer from '../components/footer'
export default ({ children }) => (
  <div>
    <Meta />
    { children }
    <Footer />
  </div>
)

With this in place, your resulting pages/index.js can look as follows:

import Page from '../layouts/main'
export default () => (
  <Page>
    <p>my page with global styles!</p>
  </Page>
)

Some notes:

  • How about pages with different global styles? You can configure multiple layouts, or pass props to <Meta> or <Page>. For example, <Page dark={true}> to embed styles that set the background to black and the font color to white and then embed a different <style> element based on this.props.dark within that component.
  • How about server rendering? <Head> takes care of shipping the underlying <style> in the <head> automatically when server rendering!
  • If you still want to modify the HTML template for all pages, you can do that by modifying _document.js see: https://github.com/zeit/next.js#custom-document
You can’t perform that action at this time.