Tutorial

Styling React Components Using glamorous

Published on May 9, 2018
Default avatar

By Alligator.io

Styling React Components Using glamorous

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

💄 glamorous is a lightweight library for CSS-in-JS with a simple API that’s similar to styled-components’ and that makes use of glamor under the hood. Two of the main differences compared to styled-components is the use of JavaScript object literals and an additional API that allows to use DOM elements directly without creating additional named components.

Let’s go over how to use glamorous to give our components some style.

Installation

To get started, you’ll need a few packages: glamorous, glamor and prop-types:

$ npm install glamorous glamor prop-types

# or, using Yarn
$ yarn add glamorous glamor prop-types

Then, all you have to do to start using it is to import the default export from the library:

SomeComponent.js
import glamorous from 'glamorous';

// ...

Basic Usage

You create a glamorous component and give it some style using the name of any DOM element and providing an object literal with CSS property names (camel-cased) and values:

import React from 'react';
import glamorous from 'glamorous';

const Box = glamorous.div({
  background: 'pink',
  marginTop: 30, // defaults to pixels
  padding: '2rem 3rem'
});

const MyComponent = () => {
  return (
    <Box>
      <h1>A title inside a pink box! 🌸</h1>
    </Box>
  );
};

export default MyComponent;

Props

You can access props passed-in to a glamorous component using a callback function as the second argument when creating the component:

import React from 'react';
import glamorous from 'glamorous';

const Box = glamorous.div(
  {
    marginTop: 30, // defaults to pixels
    padding: '2rem 3rem'
  },
  props => ({
    background: props.bg
  })
);

const MyComponent = () => {
  return (
    <Box bg="purple">
      <h1>A title inside a purple box! 🌸</h1>
    </Box>
  );
};

export default MyComponent;

Media queries, pseudo-elements & pseudo-classes

Media queries using glamorous is just as easy really:

// ...

const Box = glamorous.div({
  maxWidth: '60%',
  background: 'antiquewhite',
  margin: '1rem auto',
  padding: '2rem 3rem',
  ['@media (max-width: 600px)']: {
    maxWidth: '90%',
    background: 'lightseagreen'
  }
});

// ...

And likewise for pseudo-elements and pseudo-classes:

// ...

const Box = glamorous.div({
  maxWidth: '60%',
  background: 'antiquewhite',
  margin: '1rem auto',
  padding: '2rem 3rem',
  transition: 'background .3s',
  [':hover']: {
    background: 'lightseagreen'
  },
  [':before']: {
    content: '"Hello"',
    background: 'pink',
    padding: '.5rem 1rem'
  }
});

// ...

Notice the use of double quotes inside the single quotes for the :before pseudo-element. That syntax is important for the pseudo-element to work correctly.

Alternative Usage

For simpler and smaller components, you can also use an alternative API where you import components that correspond to a specific DOM element and use them directly. This way you avoid having to come up with a bunch of names for your glamorous components:

import React from 'react';
import { Div, H1 } from 'glamorous';

const MyComponent = () => {
  return (
    <Div background="antiquewhite" margin="1rem auto" maxWidth="60%">
      <H1 className="card-title" borderBottom="2px solid purple">
        A title inside an antique white box! 🌸
      </H1>
    </Div>
  );
};

glamorous is smart enough to distinguish between native element attributes and style props. With the above example, the card-title class will be added to the element as an additional class on top of the one generated by glamorous for the border-bottom style.

Theming

You can make use of glamorous’ ThemeProvider component to provide theme information that will be made available to all the components down the tree.

For example, here’s how you would provide a theme from the App component:

App.js
import React, { Component } from 'react';
import { ThemeProvider } from 'glamorous';

import Card from './Card';

const theme = {
  default: {
    background: '#f3f3f3',
    color: '#525252'
  },
  dark: {
    background: '#231919',
    color: '#FFDABC'
  }
};

class App extends Component {
  state = {
    currentTheme: 'default'
  };

  handleClick = () => {
    this.setState(state => ({
      currentTheme: state.currentTheme === 'default' ? 'dark' : 'default'
    }));
  };

  render() {
    const currentTheme = this.state.currentTheme;

    return (
      <ThemeProvider theme={theme[currentTheme]}>
        <React.Fragment>
          <Card />
          <Card />
          <button onClick={this.handleClick}>Toggle theme</button>
        </React.Fragment>
      </ThemeProvider>
    );
  }
}

export default App;

The button’s onClick handler toggles between our two themes and the ThemeProvider’s children components will automatically have access to the theme data.

You can access the theme from the props passed-in to the callback when creating a glamorous component:

Card.js
import React from 'react';
import glamorous from 'glamorous';

const Box = glamorous.div(
  {
    maxWidth: '60%',
    margin: '1rem auto',
    padding: '2rem 3rem'
  },
  ({ theme }) => ({
    background: theme.background,
    color: theme.color
  })
);

const MyComponent = () => {
  return (
    <Box>
      <h1>A title inside a pink box! 🌸</h1>
    </Box>
  );
};

export default MyComponent;

Global Styling

glamorous doesn’t bother itself with global styling and instead you can revert to glamor’s css.global to inject some global styles into your apps:

App.js
// ...other imports
import { css } from 'glamor';

css.global('html, body', {
  background: '#f3f3f3',
  margin: 0
});

// ...

🤓 And that’s it for our little intro to glamorous. Refer to the official docs for more advanced use cases.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about us


About the authors
Default avatar
Alligator.io

author

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
Leave a comment


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more
DigitalOcean Cloud Control Panel