Gatsby background image example
Table of contents
One of the many selling points of Gatsby is the ability to handle images. It does this with the sharp image processing library and with the gatsby-image component. I’ve talked in the past about image processing in Gatsby if you want to know more.
Today you’ll see how to use the gatsby-image
component as a background image. You’ll use the object-fit property and code from this GitHub issue.
Project setup
Create a new project with the gatsby-cli and the default starter. After the installation completes, open the folder, and start the development server:
gatsby new gatsby-background-image
cd gatsby-background-image
yarn start
Next, install styled-components
to make the component styling a bit easier. You’ll have to install the following 3 packages:
yarn add gatsby-plugin-styled-components styled-components babel-plugin-styled-components
Don’t forget to open your gatsby-config.js
, and add the highlighted line:
module.exports = {
siteMetadata: {
// site metadata
},
plugins: [
// other plugins...
`gatsby-plugin-styled-components`,
],
};
Component definition
After that, create a new file called BgImage.jsx
inside the src/components
folder. I’ll explain what happens here after the code:
If you prefer emotion over styled-components
, here’s an example with emotion and theme-ui and here’s how to set up the project for theme-ui.
import React from "react";
import PropTypes from "prop-types";
import Img from "gatsby-image";
import styled from "styled-components";
const Parent = styled.div`
position: relative;
background-color: ${({ bc }) => bc};
`;
const FakeBgImage = styled(Img)`
position: absolute;
top: 0;
left: 0;
width: 100%;
height: ${({ height }) => height};
z-index: -1;
& > img {
object-fit: cover !important;
object-position: 0% 0% !important;
font-family: "object-fit: cover !important; object-position: 0% 0% !important;";
}
@media screen and (max-width: 600px) {
height: ${({ mobileHeight }) => mobileHeight};
}
`;
const Content = styled.div`
position: absolute;
top: 0;
height: 100%;
width: 100%;
`;
const BgImage = ({
fluid,
title,
height,
mobileHeight,
overlayColor,
children,
className,
}) => (
<Parent bc={overlayColor}>
<FakeBgImage
fluid={fluid}
title={title}
height={height}
mobileHeight={mobileHeight}
/>
<Content className={className}>{children}</Content>
</Parent>
);
BgImage.propTypes = {
fluid: PropTypes.object.isRequired,
title: PropTypes.string.isRequired,
height: PropTypes.string,
mobileHeight: PropTypes.string,
overlayColor: PropTypes.string,
children: PropTypes.node,
className: PropTypes.string,
};
BgImage.defaultProps = {
height: null,
mobileHeight: null,
overlayColor: "transparent",
children: null,
className: null,
};
export default BgImage;
First of all, there is some prop validation going on at the end of the file with prop-types. There are some default props as well.
We have a Parent
component—that’s used as a container—with position: relative
. Parent
has 2 children: the FakeBgImage
and the Content
. Both of those components have position: absolute
.
FakeBgImage
is a regular gatsby-image
component—that’s why it takes fluid
and title
as props. fluid
and title
props are the only props required by the BgImage
component. It’s styled with the object-fit
CSS property, and it has a height
property (desktop) and a mobileHeight
property.
mobileHeight
.If you want to position the image differently, check the object-fit documentation.
The Content
component is positioned absolute and takes the whole space of the parent div
. Additionally, the children of the parent BgImage
component are rendered inside the Content
component. Another thing to note is that we pass to the Content
the className
prop. That means that if you extend the BgImage
with styled(BgImage)
, the styles will be applied to the Content
component.
Now let’s see how you can use that component:
Usage
Open the file for the home page which is located at src/pages/index.js
. You’ll use the gatsby-astronaut.png
that lives in the src/images
folder. Of course, you can try it with any image you like.
The first thing you want to do is to write a GraphQL query to get the image. Then, import BgImage
, and use it as shown below:
import React from "react";
import { Link, graphql } from "gatsby";
import Layout from "../components/layout";
import Image from "../components/image";
import SEO from "../components/seo";
import BgImage from "../components/BgImage";
const IndexPage = ({ data }) => (
<Layout>
<SEO title="Home" keywords={[`gatsby`, `application`, `react`]} />
<h1>Hi people</h1>
<p>Welcome to your new Gatsby site.</p>
<p>Now go build something great.</p>
<div style={{ maxWidth: `300px`, marginBottom: `1.45rem` }}>
<Image />
</div>
<BgImage
title="astronaut"
fluid={data.astronaut.childImageSharp.fluid}
overlayColor="#04040454"
>
<h2 style={{ color: "white" }}>Look at me!</h2>
</BgImage>
<Link to="/page-2/">Go to page 2</Link>
</Layout>
);
export const query = graphql`
query {
astronaut: file(relativePath: { eq: "gatsby-astronaut.png" }) {
childImageSharp {
fluid(maxWidth: 300) {
...GatsbyImageSharpFluid
}
}
}
}
`;
export default IndexPage;
That’s it! Note that I’m using a transparent black color as an overlay to make the text inside the image more readable. You can add whatever color you like to create an effect, but remember to pass a transparent color.
You can check more examples in a Gatsby starter I set up.
This example was a quick way to take advantage of the benefits gatsby-image
offers, and use it as a background image in a Gatsby application.
gatsby-image
has an empty alt
property that translates to the following HTML code: <img alt="" />
. That means that assistive technologies, such as screen readers, won’t announce the image. This is good for our use case because the image serves a decorative purpose. If you feel that the content of the image is important and it’s not only for decoration, add a description of the image with the alt
attribute. Decorative Images on W3C.Other things to read
Popular
- Reveal animations on scroll with react-spring
- Gatsby background image example
- Extremely fast loading with Gatsby and self-hosted fonts