Creating a Component for Positioning Content
For a recent client project, I’ve been helping them transform and update parts of their web presence, and one of the key updates was a brand-new home page. With initial designs to work from, I realised that one particular container could serve as a reusable component across various sections of the project.
This component is relatively simple in appearance—a background image with some text overlaid. In the designs I encountered, the text was primarily positioned in the ‘bottom left’ and ‘top center’ of the container. I thought it would be efficient to use place-self to easily define where the content should sit, allowing for a clean and flexible layout that can adapt to different content needs.
In this post, I’ll walk you through the process of creating this component, showcasing how to implement it using CSS Grid and the place-self
property.
Component Overview
Looking at the design I found three things that could be changeable.
Flexible Positioning:
Although the current designs only had the text positioned in two places, I thought we should make it more flexible and allow the content area to be in more positions. Using place-self
this component can offer nine distinct positioning options.
Custom Width:
Another feature I wanted to add was the ability to set a custom width for the content block (with a sensible default). Defining the width using CSS variables allows us to easily adapt the component to fit various design needs.
Surface Options:
The choice of background image would determine if the content block is more accessible and readable so I wanted to support two surface styles: light and dark. The light surface features a subtle gray background, providing contrast against darker images, while the dark surface offers a semi-transparent black background for improved visibility on lighter images.
Building the component structure
To effectively position content on a background image, I needed to establish a clear HTML structure for the component. Essentially, I wanted a parent and child element. The parent being the horizontal slice of the web page, a section, and a child component that holds the content but defines their position, width, and colours.
<section class="_DS-spot-content"><div class="_DS-spot-content__content" data-surface="dark" data-position="start start" style="--spot-content-width: 400px;">/* Content Goes Here */</div></section>
Now we’ve got the basics, let’s get some styling.
Styling the component
To bring our component to life, we will use CSS Grid for layout management and the place-self property for precise content positioning. This approach allows us to create a flexible and responsive design that adapts seamlessly to various screen sizes.
Using CSS Grid
CSS Grid is a powerful layout system that enables us to create complex grid-based layouts with ease. For our component, we can define a grid container that takes up the full height of the viewport, allowing us to position our content block anywhere within that space. Here's how we set up the grid layout:
._DS-spot-content {display: grid;height: 100dvh; /* Full viewport height */padding: 2rem;width: 100%;> * {grid-area: 1 / 1; /* Ensures the content block occupies the full grid area */}}
Styling with place-self
The place-self
property is a shorthand that combines both align-self
and justify-self
, allowing us to control the alignment of grid items with a single declaration. This simplifies our CSS and makes it easier to manage the positioning of content blocks.
Positioning Logic
Using place-self
, we can specify how the content block should be aligned within the grid.
[data-position="start"] {place-self: start start; /* Aligns content to the top-left */}[data-position="end"] {place-self: end; /* Aligns content to the bottom-right */}[data-position="center"] {place-self: center; /* Centers content both vertically and horizontally */}/* Additional positioning configurations */[data-position="start start"] { place-self: start start; }[data-position="start center"] { place-self: start center; }[data-position="start end"] { place-self: start end; }[data-position="center center"] { place-self: center center; }[data-position="center start"] { place-self: center start; }[data-position="center end"] { place-self: center end; }[data-position="end start"] { place-self: end start; }[data-position="end center"] { place-self: end center; }[data-position="end end"] { place-self: end end; }
Defining the width with a custom property
One of the features of this component is the ability to define the width of the content block using a custom CSS property. To implement this, we use a CSS custom property, —spot-content-width
, which can be set directly as an inline style of the HTML or defined within the CSS itself.
Having the custom property as an inline style could benefit implementation in a CSS, where a content creator can decide how wide this content block should be, like this:
<divclass="_DS-spot-content__content"data-surface="dark"data-position="start start"style="--spot-content-width: 400px;">/* Content Goes Here */</div>
We could also set a default in the CSS, if there is no inline CSS custom property:
._DS-spot-content__content {max-width: var(--spot-content-width, 50%); /* Default width set to 50% */padding: 2rem;width: 100%;}
Defining Surface Styles
As the content block will be on top of an image we need to enhance the readability and accessibility of it by defining a couple of surface/text colour styles.
We will support two distinct surface styles: light and dark. Each style is designed to provide an optimal contrast to the background image.
Light
The light option would be used when the background image is overly dark, or dark where the content is positions.
._DS-spot-content__content[data-surface="light"] {background-color: rgba(220, 220, 220, 0.5);color: black;}
Dark
The dark styling option would be for the opposite, whe nthe background image is overly bright, or bright where the content is to be positioned.
._DS-spot-content__content[data-surface="dark"] {background-color: rgba(20, 20, 20, 0.3); /* Semi-transparent dark gray */color: white; /* Text colour for better contrast */}
In the HTML we set a data attribute data-surface
:
<div class="_DS-spot-content__content" data-surface="light" data-position="center center">/* Content Goes Here */</div>
Example
We explored the process of creating a reusable component for positioning content over a background image. Using CSS Grid and the place-self
property, we achieved a flexible layout that allows for precise content placement with multiple positioning options. Additionally, we included a custom width setting and surface styles to enhance readability and adapt the component to various design needs.