Looking for a Front-End Developer and Design Systems Practitioner?

I currently have some availabilty. Let's talk!.

Always Twisted

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.

Code languagehtml
<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:

Code languagecss
._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.

Code languagecss
[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:

Code languagehtml
<div
class="_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:

Code languagecss
._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.

Code languagecss
._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.

Code languagecss
._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:

Code languagehtml
<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.

Unsure how to structure your design tokens for scalability and future growth?

I can help define a scalable structure for your tokens, ensuring they grow with your system.

get in touch!