Ibadehin Mojeed I'm an advocate of project-based learning. I also write technical content around web development.

Bidirectional CSS centering: A complete guide

6 min read 1774

Bidirectional CSS Centering: A Complete Guide

When working with CSS, we think of page elements as boxes, and the arrangement of these boxes presents the concept of the CSS layout.

Naturally, every page element has a normal position inside the document layout flow. But oftentimes, we alter the default behavior to create the exact layout that we want. This occurs when we want to center objects inside another object within our document.

This is a common task during development, and yet, over the years, this task seems to have become difficult and complex, especially when it comes to centering on the vertical axis.

This makes developers resort to all sorts of unmanageable hacks and workarounds, like using CSS table properties that cause inconsistencies in browsers and fail on screen readers or using absolute positioning with negative margins that only centers objects of a specified width.

Another trick is using position: absolute; and the transform property to center elements in a container. But, this method can create awkward layouts and only allows one element per container without additional work.

In essence, developers use different hacks to center objects depending on the task, which is where the pain of centering objects comes from: there are too many workarounds.

In modern CSS, however, we don’t need to go through this stress any longer because we now have more control over how we center objects in bidirectional layouts.

In this guide, we will look at the modern bidirectional centering techniques in CSS while following best practices to center objects that scale nicely across devices and screens.

Understanding bidirectional CSS centering

As the name implies, bidirectional centering literally means “two-directional centering.”

In the context of CSS, it’s interpreted as centering objects in two directions, that is, both the horizontal direction, also called the main axis, and the vertical direction also called the cross axis.

We made a custom demo for .
No really. Click here to check it out.

We can also think of bidirectional as anything that functions in two opposite directions and is unaffected by the flow’s direction.

By applying this concept in the context of CSS, bidirectional centering centers objects that are not affected by changing the layout flow’s direction.

In other words, the object remains in the center irrespective of the layout flow, that is, whether the writing direction is left to right, ltr, like English text; rtl, like Arabic text; or when the writing mode is set to vertical-*, like Japanese and Mongolian.

Unidirectional centering

Unidirectional centering involves one-directional centering, meaning centering an object either horizontally or vertically. In this case, the object’s center alignment is dependent on the direction of the layout’s flow.

Let’s take a look at how unidirectional centering works to better understand how bidirectional centering works.

Here, we have an HTML markup that generates the following layout:

<div class="container">
  <div class="obj">Center this obj</div>
</div>

Generated Layout Showing Horizontal And Vertical Axis With Grey Object Box In Left-Hand Corner

We styled the object to see the initial position in the document layout flow considering an ltr writing direction. Now, by centering the object vertically inside its container, we have the following:

Centering Object Vertically, Object Appears On Left-Hand Side In Center

Here, we can use the CSS flex to center the object vertically:

.container {
  display: flex;
  align-items: center;
  /* ... */
}

For now, ignore the code and focus on the object positioning. If we change the writing mode or the writing direction of this document, the object’s vertical center alignment tends to be affected.

The code below changes the writing mode to vertical-*, as we would find in Mongolian text:

.container {
  /* ... */
  writing-mode: vertical-lr;
}

This additional style produces a new layout:

Unidirectional Centering On Horizontal Axis, Grey Object Is Centered On Top

As we can see, the object’s center alignment depends on the direction of the layout flow, which is unidirectional centering.

On the other hand, with bidirectional centering, an object must remain in the center no matter the direction of the layout flow, as seen below.

Bidirectional Centering Object On Both Axis In Center

Next, let’s see how to achieve this type of object centering.

Object centering using the position and transform properties

As mentioned earlier, using the position: absolute; method is considered a legacy technique. But the essence of using this trick is for us to see the limitations and to better appreciate the modern techniques that we will cover afterward.

Let’s revisit our earlier markup:

<div class="container">
  <div class="obj">Center this obj</div>
</div>

To center the child element within the container, we can simply apply this code:

.container {
  position: relative;
  /* ... */
}

.obj {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  /* ... */
}

By making the container a position: relative; and the element to center a position: absolute; means we can move the element to the center of the container (see at CodeSandbox).

Centering An Object Inside A Container

One limitation of using this method is that it usually only allows one element per container without additional styles. It can also cause an awkward layout due to overlapping text.

So, instead of using this hack or any of the others, we will learn the modern techniques.

Object centering using CSS flexbox

With CSS flexbox, we can easily control the placement of objects inside another object. When we apply display: flex to a parent element, it means we want the direct children to become flex items so we can apply the alignment properties to control the items.

Again, let’s use the earlier HTML markup:

<div class="container">
  <div class="obj">Center this obj</div>
</div>

By making the container element a flex container and applying the alignment properties, as seen below, we have the child element perfectly centered in the container (see at CodeSandbox):

.container {
  display: flex;
  align-items: center;
  justify-content: center;

  /* ... */
}

Centering The Child Element With The Flex Container Alignment Properties

The align-items:center; applied to the flex container centers the child element vertically while the justify-content: center; centers the element in the main axis, that is, horizontally.

One of the advantages of this method over the traditional techniques is flexibility. We can center more than one object seamlessly within a container, and that alone encourages code maintainability.

A practical example of bidirectional centering using flexbox

We can find real-life examples when dealing with the hero section of a page, a pop-up message, or centered overlays.

In this section, we will see how we can perfectly center the hero contents of a page. Let’s consider the following markup:

<section class="hero">
  <h1>
    <!-- ... -->
  </h1>
  <p>
    <!-- ... -->
  </p>
  <button>Contact us</button>
</section>

We’ve removed the content from the code for brevity (see at CodeSandbox).

By applying the flex and the alignment properties on the parent container element, section, we have the children elements perfectly centered in the container:

.hero {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;

  /* ... */
}

We then get the following result:

Applying Flex And Alignment Properties To Parent Container Element

In the CSS code, we added a flex-direction: column; alongside the alignment properties to make the content position along the cross axis.

This is because flexbox is a one-dimensional layout model, meaning it processes layouts in one dimension at a time, either row or column. And, by default, the flex-direction is set to row, making the content position along the main axis.

By adding the flex-direction: column;, we change the default to align vertically.

Centering images and inline elements

This method does not only work for centering text blocks as we’ve seen above; we can also center images and inline elements like the anchor text link.

In a real-life project, we might want to add an image and a text link alongside other text blocks to the center. So, let’s see the markup for that and implement the flexbox method to center the content:

<section class="hero">
  <img src="..." alt="" />
  <h1>...</h1>
  <p>...</p>
  <a href="#">...</a>
</section>

Again, we removed the elements’ content for brevity (see at CodeSandbox). Using the same flexbox properties, we have our content perfectly centered, like so:

Centering Objects With Flexbox

As we can see with flexbox, centering objects is simple and manageable. This method is so flexible that we can add or remove content to/from the flex container and still have perfect centering without additional styles.

In almost all cases in our real-life project, we will often use this method for centering objects.

Flexbox browser support

Flexbox is supported by all modern browsers, so we can confidently use it for centering objects in our layout. See the current browser support here.

Flexbox Browser Support

Object centering using the CSS grid

Like flexbox, we can also apply a display: grid; to a container element so the direct children become grid items. Then, we can use the alignment properties to center the content within the container.

The following CSS code centers objects within a container:

.container {
  display: grid;
  place-content: center;

  /* ... */
}

This CSS produces the same center alignment as that of the flexbox example (see at CodeSandbox).

Here, we are only using two lines of CSS. The place-content CSS property controls how the content is aligned and justified at the same time. And, by assigning a center value, the items will centrally align within the container.

The place-content is shorthand for align-content and justify-content, meaning we can rewrite the above CSS to look like this:

.container {
  display: grid;
  align-content: center;
  justify-content: center;
  /* ... */
}

A practical example of bidirectional centering using the grid

Using the same hero example as covered in the flexbox section, let’s apply the following grid styles instead:

.hero {
  display: grid;
  place-content: center;
  /* ... */
}

We then have the following output (see at CodeSandbox):

Output With Grid Styles

As seen in the image, the Contact us button takes the width of the surrounding content. This is because when the CSS place-content property applies to a grid container, the grid items immediately take the size of the item with the largest width.

This effect brings the differences when compared to the flexbox method. And now, depending on the layout that we want, we can easily decide which of these methods to use.

But again, in most cases, we will use the flexbox to center objects because it can seamlessly produce any centered layout that we want.

Grid layout browser support

The grid, unlike flexbox, has less browser support.

Grid Browser Support

Conclusion

Instead of going through tens of techniques including the unnecessary legacy hacks to center objects, we now have modern ways we can use to center any type of object.

We also covered real-life examples and best practices so we know how to apply them in our own projects.

I hope you enjoyed reading this guide. If you have questions or contributions, please share them in the comment section. And lastly, endeavor to share this guide around the web.

Is your frontend hogging your users' CPU?

As web frontends get increasingly complex, resource-greedy features demand more and more from the browser. If you’re interested in monitoring and tracking client-side CPU usage, memory usage, and more for all of your users in production, try LogRocket.https://logrocket.com/signup/

LogRocket is like a DVR for web apps, recording everything that happens in your web app or site. Instead of guessing why problems happen, you can aggregate and report on key frontend performance metrics, replay user sessions along with application state, log network requests, and automatically surface all errors.

Modernize how you debug web apps — .

Ibadehin Mojeed I'm an advocate of project-based learning. I also write technical content around web development.

Leave a Reply