Implementing Dark Mode In React Apps Using styled-components

Implementing Dark Mode In React Apps Using styled-components

Implementing Dark Mode In React Apps Using styled-components

Blessing Krofegha

One of the most commonly requested software features is dark mode (or night mode, as others call it). We see dark mode in the apps that we use every day. From mobile to web apps, dark mode has become vital for companies that want to take care of their users’ eyes.

Dark mode is a supplemental feature that displays mostly dark surfaces in the UI. Most major companies (such as YouTube, Twitter, and Netflix) have adopted dark mode in their mobile and web apps.

While we won’t go in depth into React and styled-components, a basic knowledge of React, CSS, and styled-components would come in handy. This tutorial will benefit those who are looking to enhance their web applications by catering to those who love dark mode.

StackOverflow announces dark mode on Twitter
StackOverflow announces dark mode on Twitter (Large preview)

A few days before the writing of this article, StackOverflow announced its release of dark mode, giving users the chance to toggle between the two modes.

Dark mode reduces eye strain and helps when you’re working for a long time on a computer or mobile phone.

What Is Dark Mode?

Dark mode is the color scheme of any interface that displays light text and interface elements on a dark background, which makes the screen a little easier to look at mobile phones, tablets, and computers. Dark mode reduces the light emitted by the screen, while maintaining the minimum color-contrast ratios required for readability.

Why Should You Care About Dark Mode?

Dark mode enhances visual ergonomics by reducing eye strain, adjusting the screen to current light conditions, and providing ease of use at night or in dark environments.

Before implementing dark mode in our app, let’s look at its benefits.

Battery Saving

Dark mode in web and mobile apps can prolong the battery life of a device. Google has confirmed that dark mode on OLED screens has been a huge help to battery life.

For example, at 50% brightness, dark mode in the YouTube app saves about 15% more screen energy than a flat white background. At 100% screen brightness, the dark interface saves a whopping 60% of screen energy.

Dark Mode Is Beautiful

Dark mode is beautiful, and it can significantly enhance the appeal of the screen.

While most products are going for that similar bland white look, dark mode offers something different that feels mysterious and new.

It also provides great opportunities to present graphic content such as dashboards, pictures, and photos in a fresh way.

Twitter dark versus light mode
The beauty of Twitter’s dark mode over light mode (Large preview)

Now that you know why you should implement dark mode in your next web app, let’s dive deep into styled-components, which is the defining resource of this tutorial.

Dark mode is the color scheme of any interface that displays light text and interface elements on a dark background, which makes it a little easier to look at on mobile phones, tablets, and computers.

What Are styled-components?

Throughout this article, we will be using the styled-components library very often. There have always been many ways to style a modern web app. There’s the traditional method of styling at the document level, which includes creating an index.css file and linking it to the HTML or styling inside the HTML file.

A lot has changed in the ways that web apps are styled recently, since the introduction of CSS-in-JS.

CSS-in-JS refers to a pattern in which CSS is composed using JavaScript. It utilizes tagged template literals to style components in a JavaScript file.

To learn more about CSS-in-JS, check out Anna Monus’s article on the subject.

styled-components is a CSS-in-JS library lets you use all of the features of CSS that you love, including media queries, pseudo-selectors, and nesting.

Why styled-components?

styled-components was created for the following reasons:

  • No class name hell
    Instead of you scratching your head to find a class name for an element, styled-components generates unique class names for your styles. You’ll never have to worry about misspellings or using class names that have no meaning.
  • Using props
    styled-components allow us to extend styling properties using the props parameter, commonly used in React — thus, dynamically affecting the feel of a component via the application’s state.
  • Supports Sass syntax
    Writing Sass syntax out of the box without having to set up any preprocessors or extra build tools is possible with styled-components. In your style definitions, you can use the & character to target the current component, use pseudo-selectors, and experiment with nesting.
  • Theming
    styled-components have full theming support by exporting a ThemeProvider wrapper component. This component provides a theme to all React components within itself via the Context API. In the rendering tree, all styled-components will have access to the provided theme, even when they are multiple levels deep. As we continue in this tutorial, we will look deeper into the theming features of styled-components.

To learn more advantages of styled-components, check out Kris Guzman’s article.

Implementing Dark Mode

In this article, we are going to implement dark mode on a simple YouTube-like web page.

To follow along, ensure that you clone the original repository from the starter branch.

Setting Up

Let’s install all of the dependencies in our package.json file. From the terminal, run the following command:

npm install

Upon its successful installation, run npm start. Here is what the web page looks like without dark mode implemented on it.

The web page to be used, without dark mode
The web page to be used, without dark mode. (Large preview)

To install styled-components, in your terminal run npm install styled-components.

Implementation

To implement dark mode, we need to create four different components.

  • Theme
    This contains the color properties of our light and dark themes.
  • GlobalStyles
    This contains the global styles for the entire document.
  • Toggler
    This holds the button element that toggles the functionality.
  • useDarkMode
    This custom hook handles the logic behind the change of theme and the persistence of our theme in localStorage.

Theme Component

In the src folder, you’ll see components in the components folder. Create a Themes.js file, and add the following code to it.

export const lightTheme = {
    body: '#FFF',
    text: '#363537',
    toggleBorder: '#FFF',
    background: '#363537',
}
export const darkTheme = {
    body: '#363537',
    text: '#FAFAFA',
    toggleBorder: '#6B8096',
    background: '#999',
}

Here, we’ve defined and exported lightTheme and darkTheme objects with distinct color variables. Feel free to experiment and customize the variables to suit you.

globalStyles Component

Remaining in your components folder, create a globalStyles.js file, and add the following code:

import { createGlobalStyle} from "styled-components"
export const GlobalStyles = createGlobalStyle`
  body {
    background: ${({ theme }) => theme.body};
    color: ${({ theme }) => theme.text};
    font-family: Tahoma, Helvetica, Arial, Roboto, sans-serif;
    transition: all 0.50s linear;
  }
  `

We’ve imported createGlobalStyle from styled-components. The createGlobalStyle method replaces the now deprecated injectGlobal method from styled-components version 3. This method generates a React component, which, when added to your component tree, will inject global styles into the document, in our case, App.js.

We defined a GlobalStyle component and assigned background and color properties to values from the theme object. Thus, every time we switch the toggle, the values will change depending on the dark theme or light theme objects that we are passing to ThemeProvider (which will be created later, as we proceed).

The transition property of 0.50s enables this change to occur a little more smoothly, so that as we toggle back and forth, we can see the changes happen.

Creating Theme-Toggling Functionality

To implement the theme-toggling functionality, we need to add only a few lines of code. In the App.js file, add the following code (note that the highlighted code is what you should add):

import React, { useState, useEffect } from "react";
import {ThemeProvider} from "styled-components";
import { GlobalStyles } from "./components/Globalstyle";
import { lightTheme, darkTheme } from "./components/Themes"
import "./App.css";
import dummyData from "./data";
import CardList from "./components/CardList";
const App = () => {
const [videos, setVideos] = useState([]);
const [theme, setTheme] = useState('light');
const themeToggler = () => {
  theme === 'light' ? setTheme('dark') : setTheme('light')
}
useEffect(() => {
    const timer = setTimeout(() => {
      setVideos(dummyData);
    }, 1000);
    return () => clearTimeout(timer);
  }, []);
  return (
    <ThemeProvider theme={theme === 'light' ? lightTheme : darkTheme}>
      <>
      <GlobalStyles/>
          <div className="App">
            <button onClick={themeToggler}>Switch Theme</button>
      {
      videos.map((list, index) => {
        return (
          <section key={index}>
            <h2 className="section-title">{list.section}</h2>
            <CardList list={list} />
            <hr />
          </section>
        );
      })}
        </div>
      </>
    </ThemeProvider>

  );
};
export default App;

The highlighted code is the one newly added to App.js. We’ve imported ThemeProvider from styled-components. ThemeProvider is a helper component in the styled-components library that provides theming support. This helper component injects a theme into all React component below itself via the Context API.

In the rendering tree, all styled-components will have access to the provided theme, even when they are multiple levels deep. Check out the section on “Theming”.

Next, we import the GlobalStyle wrapper from ./components/Globalstyle. Lastly, from the top, we import both the lightTheme and darkTheme objects from ./components/Themes.

In order for us to create a toggling method, we need a state that holds our theme’s initial color value. So, we create a theme state, and set the initial state to light, using the useState hook.

Now, for the toggling functionality.

The themeToggler method uses a ternary operator to check the state of the theme, and it toggles either dark or light based on the value of the condition.

ThemeProvider, a styled-components helper component, wraps everything in the return statement and injects any components below it. Remember that our GlobalStyles inject global styles into our components; hence, it’s called inside the ThemeProvider wrapper component.

Lastly, we created a button with an onClick event that assigns our themeToggler method to it.

Let’s see the outcome thus far.

Dark mode implemented without persistence.
Dark mode implemented without persistence (Large preview)

Our App.js file needs to be refactored; a lot of its code is not DRY. (DRY stands for “don’t repeat yourself”, a basic principle of software development aimed at reducing repetition.) All of the logic seems to be in App.js; it’s good practice to separate our logic for the sake of clarity. So, we’ll create a component that handles the toggling functionality.

Toggle Component

Still within the components folder, create a Toggler.js file, and add the following code to it:

import React from 'react'
import { func, string } from 'prop-types';
import styled from "styled-components"
const Button = styled.button`
  background: ${({ theme }) => theme.background};
  border: 2px solid ${({ theme }) => theme.toggleBorder};
  color: ${({ theme }) => theme.text};
  border-radius: 30px;
  cursor: pointer;
  font-size:0.8rem;
  padding: 0.6rem;
  }
\`;
const Toggle = ({theme,  toggleTheme }) => {
    return (
        <Button onClick={toggleTheme} >
          Switch Theme
        </Button>
    );
};
Toggle.propTypes = {
    theme: string.isRequired,
    toggleTheme: func.isRequired,
}
export default Toggle;

To keep things neat, we’ve styled our toggle button in the Toggle component, using the styled function from styled-components.

This is purely for presentation; you can style the button as you see fit.

Inside the Toggle component, we pass two props:

  • the theme provides the current theme (light or dark);
  • the toggleTheme function will be used to switch between themes.

Next, we return the Button component and assign a toggleTheme function to the onClick event.

Lastly, we use propTypes to define our types, ensuring that our theme is a string and isRequired, while our toggleTheme is func and isRequired.

Using Custom Hooks (useDarkMode)

When building an application, scalability is paramount, meaning that our business logic must be reusable, so that we can use it in many places and even in different projects.

That is why it would be great to move our toggling functionality to a separate component. For that, we would create our own custom hook.

Let’s create a new file named useDarkMode.js in the components folder, and move our logic to this file, with some tweaks. Add the following code to the file:

import { useEffect, useState } from 'react';
export const useDarkMode = () => {
    const [theme, setTheme] = useState('light');

    const setMode = mode => {
        window.localStorage.setItem('theme', mode)
        setTheme(mode)
    };

    const themeToggler = () => {
        theme === 'light' ? setMode('dark') : setMode('light')
    };

    useEffect(() => {
        const localTheme = window.localStorage.getItem('theme');
        localTheme && setTheme(localTheme)
    }, []);
    return [theme, themeToggler]
};

We’ve added a few things here.

  • setMode We use localStorage to persist between sessions in the browser. So, if a user has chosen the dark or light theme, that’s what they’ll get upon their next visit to the app or if they reload the page. Hence, this function sets our state and passes theme to localStorage.
  • themeToggler This function uses a ternary operator to check the state of the theme and toggles either dark or light based on the truth of the condition.
  • useEffect We’ve implemented the useEffect hook to check on component mounting. If the user has previously selected a theme, we will pass it to our setTheme function. In the end, we will return our theme, which contains the chosen theme and the themeToggler function to switch between modes.

I think you’ll agree that our dark-mode component looks sleek.

Let’s head over to App.js for the final touches.

import React, { useState, useEffect } from "react";
import {ThemeProvider} from "styled-components";
import  {useDarkMode} from "./components/useDarkMode"
import { GlobalStyles } from "./components/Globalstyle";
import { lightTheme, darkTheme } from "./components/Themes"
import Toggle from "./components/Toggler"
import "./App.css";
import dummyData from "./data";
import CardList from "./components/CardList";
const App = () => {
const [videos, setVideos] = useState([]);
const [theme, themeToggler] = useDarkMode();
const themeMode = theme === 'light' ? lightTheme : darkTheme;

useEffect(() => {
  const timer = setTimeout(() => {
    setVideos(dummyData);
  }, 1000);
  return () => clearTimeout(timer);
}, []);

return (
  <ThemeProvider theme={themeMode}>
    <>
      <GlobalStyles/>
        <div className="App">
        <Toggle theme={theme} toggleTheme={themeToggler} />
          {
            videos.map((list, index) => {
              return (
                <section key={index}>
                  <h2 className="section-title">{list.section}</h2>
                  <CardList list={list} />
                  <hr />
                </section>
              );
            })}
        </div>
      </>
    </ThemeProvider>
  );
};
export default App;

The highlighted code is newly added to App.js.

First, we import our custom hook, destructure the theme and themeToggler props, and set it with the useDarkMode function.

Note that the useDarkMode method replaces our theme state, which was initially in App.js.

We declare a themeMode variable, which renders either a light or dark theme based on the condition of the theme mode at the time.

Now, our ThemeProvider wrapper component is assigned our just recently created themeMode variable to the theme prop.

And lastly, in place of the regular button, we pass in the Toggle component.

Remember that in our Toggle component, we defined and styled a button and passed both theme and toggleTheme to them as props. So, all we have to do is pass these props appropriately to the Toggle component, which will act as our button in App.js.

Yes! Our dark mode is set, and it persists, not changing color when the page is refreshed or visited in a new tab.

Let’s see the outcome in action:

Dark mode implemented, but with a glitch in the button color when the browser reloads.
Dark mode implemented, but with a glitch in the button color when the browser reloads. (Large preview)

Almost everything works well, but there is one small thing we can do to make our experience splendid. Switch to the dark theme and then reload the page. Do you see that the blue color in the button loads before the gray for a brief moment? That happens because our useState hook initiates the light theme initially. After that, useEffect runs, checks localStorage, and only then sets the theme to dark. Let’s jump over to our custom hook useDarkMode.js and add a little code:

import { useEffect, useState } from 'react';
export const useDarkMode = () => {
    const [theme, setTheme] = useState('light');
    const [mountedComponent, setMountedComponent] = useState(false)
    const setMode = mode => {
        window.localStorage.setItem('theme', mode)
        setTheme(mode)
    };
    const themeToggler = () => {
        theme === 'light' ? setMode('dark') : setMode('light')
    };
    useEffect(() => {
        const localTheme = window.localStorage.getItem('theme');
        localTheme ? setTheme(localTheme) : setMode('light')
        setMountedComponent(true)
    }, []);
    return [theme, themeToggler, mountedComponent]
};

The highlighted code is the only one added to useDarkMode.js. We’ve created another state named mountedComponent and set the default value to false using the useState hook. Next, inside the useEffect hook, we set the mountedComponent state to true using setMountedComponent. Lastly, in the return array, we include the mountedComponent state.

Finally, let’s add a bit of code in App.js to make it all work.

import React, { useState, useEffect } from "react";
import {ThemeProvider} from "styled-components";
import  {useDarkMode} from "./components/useDarkMode"
import { GlobalStyles } from "./components/Globalstyle";
import { lightTheme, darkTheme } from "./components/Themes"
import Toggle from "./components/Toggler"
import "./App.css";
import dummyData from "./data";
import CardList from "./components/CardList";
const App = () => {
  const [videos, setVideos] = useState([]);
  const [theme, themeToggler, mountedComponent] = useDarkMode();
  const themeMode = theme === 'light' ? lightTheme : darkTheme;
  useEffect(() => {
    const timer = setTimeout(() => {
      setVideos(dummyData);
    }, 1000);
    return () => clearTimeout(timer);
  }, []);
  if(!mountedComponent) return <div/>
  return (
    <ThemeProvider theme={themeMode}>
      <>
      <GlobalStyles/>
        <div className="App">
          <Toggle theme={theme} toggleTheme={themeToggler} />
          {
            videos.map((list, index) => {
              return (
                <section key={index}>
                  <h2 className="section-title">{list.section}</h2>
                  <CardList list={list} />
                  <hr />
                </section>
              );
            })}
        </div>
      </>
    </ThemeProvider>

  );
};
export default App;

We’ve added our mountedComponent state as a prop in our useDarkMode hook, and we’ve checked whether our component has mounted, because this is what happens in the useEffect hook. If it hasn’t happened yet, then we will render an empty div.

Let’s see the outcome of our dark-mode web page.

Final result of dark mode
Final result of dark mode (Large preview)

Now, you’ll notice that while in dark mode, when the page reloads, the button’s color doesn’t change.

Conclusion

Dark mode is increasingly becoming a user preference, and implementing it in a React web app is a lot easier when using the ThemeProvider theming wrapper in styled-components. Go ahead and experiment with styled-components as you implement dark mode; you could add icons instead of a button.

Please do share your feedback and experience with the theming feature in styled-components in the comments section below. I’d love to see what you come up with!

The supporting repository for this article is available on GitHub. Also, check it out on CodeSandbox.

References

Smashing Editorial (ks, ra, il, al)

Movie Poster Designs To Inspire Your PWA Hero Images

Movie Poster Designs To Inspire Your PWA Hero Images

Movie Poster Designs To Inspire Your PWA Hero Images

Suzanne Scacca

I visited the Fandango website last weekend, hoping to find something that would give me an excuse to spend a couple of hours inside an air-conditioned movie theater. This is what first caught my eye when I got there:

The Fandango home page shows a slider with popular movies and their posters
The Fandango home page shows a slider with popular movies and their posters. (Image credit: Fandango) (Large preview)

To be honest, most of these movie posters did absolutely nothing to motivate me to leave the house. Except for The Lion King, which has such a striking color palette, and Once Upon a Time in Hollywood, which does some cool stuff with typography.

Has anyone else ever experienced this before? You’re in the mood to watch a movie and either:

  • Catch a glimpse of the movie poster you were interested in, only to question whether or not it’s even worth watching?
  • Catch a glimpse of a movie poster you hadn’t given much thought to, but then changed your plan and saw that one instead?

And we’re not even talking about movie trailers here. We’re talking about what a single poster designed to promote a movie and entice people to watch it can do to your perception of it.

If you think about it, the hero image on a PWA has just as much sway over a first-time visitor.

You have only a few seconds to make an impression with your hero image. How do you want yours to make visitors feel?

Do your visitors proceed through the PWA with excitement over what they’re about to find? Or do they do so with apprehension due to disappointment or confusion caused by the first image?

Let’s look at some examples of good and bad movie posters and see what sort of lessons we can use to help you with your PWA hero design:

1. Avoid Stock Photos When You Can

In other parts of a PWA, high-quality stock photos purchased from sites like Getty or iStock may suffice. But your hero image?

I’d say you should be very careful with this, especially if using a stock photo that’s easily recognizable. Even if it’s an attractive photo and aligns perfectly well with the brand’s story, do you really think someone else’s imagery belongs at the top of the PWA?

When Aquaman came out in 2018, they released a series of movie posters to promote it. However, it was this particular poster that caused a huge uproar online:

The Aquaman movie poster includes stock photos of sharks
The Aquaman movie poster includes stock photos of sharks. (Image credit: “Aquaman” on IMDB) (Large preview)

Essentially, the complaints on Twitter boiled down to the usage of this stock photo from Getty:

Twitter users were in an uproar over the Aquaman movie poster
Twitter users were in an uproar over the Aquaman movie poster. (Image credit: Twitter) (Large preview)

Now, you can expect there to be arguments whenever any major criticism is made of a superhero movie. With camps clearly divided between Marvel and DC movies, it’s kind of hard not to want to defend your superheroes tooth and nail when someone insults them. Even if it’s because of a stock photo of a shark.

The people against the criticism have a point though. It’s not like the real stars of the movie could be submerged in a body of water with live sharks. Aside from stock photography or CGI, what choice did the poster designers really have?

That said, I think what the real issue is, is that this is a huge movie with a huge studio budget, and the inclusion of a stock photo makes you wonder if they cut corners anywhere else in the film.

The usage of recognizable stock photos in a hero image may send the same sort of signal to visitors if they’re expecting an end-to-end premium experience from the brand behind it.

2. Make It Unique

If you watch as many movies as I do, you’re bound to notice certain trends when it comes to movie posters. This is especially so in the rom-com genre where it almost feels like designers don’t bother to be original or creative.

While this lookalike quality of movie posters can help fans of certain genres instantly identify the kinds of movies they want to watch, it sends another signal to them as well.

If you don’t know who Nicholas Sparks is, he’s the author of over twenty books, most of which have similar plots.

I’m going to let this Vanity Fair movie poster compilation demonstrate my point:

A Vanity Fair article shows off various covers from Nicholas Sparks movies
A Vanity Fair article shows off various covers from Nicholas Sparks movies. (Image credit: Vanity Fair) (Large preview)

If you were to talk to someone about one of these movies, it could be summed up as:

“You know the movie… The one with the boy and the girl who don’t really like each other at first, but then they fall madly in love and can’t stand to be apart? Oh yeah and there’s that person who dies in the end.”

That describes about 80% of these stories, which is why it’s not all that surprising that the movie posters for each look so darn similar.

Like I said, a similarly designed poster could work in their favor if they were trying to appeal to a very specific subset of moviegoers. But it doesn’t work that way with PWAs.

Unless you’re building a PWA to directly complement another brand, there’s no reason to design your hero image to look similar to anyone else’s. It’ll only cause confusion when visitors pick up on the similarities. Or they’ll wonder why they’re bothering to look at the PWA, assuming that it’s not just the images that look the same, but the services and products within, too.

If you want your PWA to stand out from the crowd, your hero image should be unique.

3. Zero In On One Thing

One of the problems with making a movie with an all-star cast is that’s it’s impossible to focus on just one person — not just within the plot, but in the movie poster as well.

Case in point: What to Expect When You’re Expecting:

The all-star cast from What to Expect When You’re Expecting
The all-star cast from What to Expect When You’re Expecting. (Image credit: “What To Expect When You’re Expecting” on IMDB) (Large preview)

If I were just stumbling upon this poster for the first time, I wouldn’t know where to start with it.

The title being in the middle helps, but the competing photos are overwhelming. Plus, if you look closely at the top photo, you’ll see that each of the women was individually layered into the picture. Why use a poorly compiled photo beside an actual shot from the movie? It creates a very disjointed experience.

To show you what a difference a singular focus can make, let’s look at the movie poster for E.T. the Extra-Terrestrial:

The poster for E.T. highlights the relationship between the boy and the alien
The poster for E.T. highlights the relationship between the boy and the alien. (Image credit: “E.T. the Extra-Terrestrial” on IMDB) (Large preview)

It’s not as though this film is without a great cast of stars. It’s just that the team who designed this recognized that there’s one real focus at the heart of the movie and it’s the relationship between Elliott (the boy) and E.T. (the alien).

I’d urge you to look for something similar when designing your hero image — even if your clients come to you and say that all of their services are equally important and they want the PWA to demonstrate that they can do all things for everyone. If you try to translate that sort of message into an image, it’s going to fail. So, find your focus.

4. Give The City A Subtle Nod

Movies can take place in any number of settings. Depending on what kind of movie it is, you may even find that the setting almost becomes a character within the story. Let me explain.

Richard Linklater filmed a trilogy of movies with Julie Delpy and Ethan Hawke.

The first movie is called Before Sunrise and takes place when Delpy and Hawke decide to get off a train and walk around the city of Vienna before parting the next morning:

The Before Sunrise movie poster features Vienna in the background
The Before Sunrise movie poster features Vienna in the background. (Image credit: “Before Sunrise” on IMDB) (Large preview)

The second movie is called Before Sunset and it takes place around the city of Paris:

The Before Sunset movie poster features Paris in the background
The Before Sunset movie poster features Paris in the background. (Image credit: “Before Sunset” on IMDB) (Large preview)

The final movie is called Before Midnight and it takes place in Greece:

The Before Midnight movie poster features a sunny Greek island in the background
The Before Midnight movie poster features a sunny Greek island in the background. (Image credit: “Before Midnight” on IMDB) (Large preview)

In each of these posters, you can see that the backdrop of the story plays heavily into the design. And that’s because there really is no story without their geographic surroundings.

They’re not just movies about two people talking to one another. It’s about two people getting to know one another as they explore a new city — a city which almost becomes like a third character that the viewer becomes acquainted with throughout the films.

If the company for whom you’re designing has a strong tie to a specific geographic region, see if you can find a way to incorporate it into the hero image somehow. It doesn’t have to be this explicit with the actual cityscape in the background. But there may be other ways to add a special touch that has local visitors thinking, “Hey, that’s where I’m from!” or “I’ve been there!”

5. Be Creative With White Space

You already know that white space is an important part of design, especially when you’re trying to convey a big message above-the-fold on a PWA. So as not to overwhelm visitors, you want to keep things simple. But that doesn’t mean you can’t be creative with how you fill that white space.

Take, for instance, the poster for Independence Day:

The Independence Day poster fills its white space with a spaceship
The Independence Day poster fills its white space with a spaceship. (Image credit: “Independence Day” on IMDB) (Large preview)

Although the space ship does convey a sense of dread, it’s also a really creative way to fill up all of the white space that would otherwise occupy the top of this photo.

Another fun example of playing with white space can be seen in the poster for Scarface:

The Scarface movie poster designers likely used symbolism to create this white space
The Scarface movie poster designers likely used symbolism to create this white space. (Image credit: “Scarface” on IMDB) (Large preview)

At first glance, you might just take this for the striking image that it is. However, knowing that Tony Montana is the head of a drug cartel and has an obscene penchant for snorting coke, the white that consumes him takes on another meaning here.

This one is a bit difficult to give you strict guidance on since this is all about being creative with the space that you have. What I would suggest if you want to go this route, though, is to think of ways to play with symbolism without having to explicitly present them within the photo. If you can play with shadows and light and space to do so, that would have a much greater impact.

6. Be Playful With Typography

For the most part, designers of movie posters tend to be very conservative when it comes to typography. They choose a single color for the font and it’s almost always a big blocky sans serif font.

But why not have a little fun with it? Just as you can imbue the image with creative flourishes, it wouldn’t be such a bad idea to do the same with text so long as the two complement one another.

You’ll find a beautiful example of this in the John Wick poster:

The John Wick movie poster typography has a unique edge
The John Wick movie poster typography has a unique edge. (Image credit: “John Wick” on IMDB) (Large preview)

If you were to quickly glance at the image, you might not pick up on the subtleties of the design. But they’re there.

For starters, the barrel of the gun takes the place of the letter “o”. But notice how the rim is tinged in the same color as the rest of the letters? This is what helps it blend so well at first glance.

Then, you have the unhinged look of the letters themselves, where they’re split and slanted through the middle.

For those of you who haven’t seen the film, this is essentially what’s happening to Keanu Reeves’s character. He was once an assassin, but gave it up for love. When his wife dies and the last remnants of her are taken from him, he’s torn. Does he continue the life of a normal man? Or does he give it all up and go on a murderous rampage?

I know that the smart thing to do when designing a hero image is to let the image tell the story, but I think subtle touches to the text can really take it up a notch.

Wrapping Up

So, what have we learned here? Well, there’s certainly a right and wrong way to go about designing a movie poster and PWA. But, more than that, the most important thing to do is to put some real thought into what you want those first few seconds to convey to your viewers.

If you fail to capture what the PWA is about or you do so in a manner that’s boring, unoriginal, vague or cheesy, you’re going to lose their interest almost immediately.

But…

If you can perfectly capture what a brand is all about along with the subtle nuances that make it special, you’ll encourage more visitors to scroll and click with a single image.

Recommended Reading on SmashingMag:

Smashing Editorial (ra, il)