Block Centered on the Screen

6 ways to center a block vertically and horizontally.

Time to read: 6 min

Task

You have the task of centering a block in the center of the screen both vertically and horizontally. Let's assume this will be a popup. In this recipe, we will consider all existing ways to solve the problem as of now.

Ready Solution

Below are all possible ways to center an element. Choose one of them.

Centering with grids:

        
          
          .parent {  display: grid;  place-items: center;}
          .parent {
  display: grid;
  place-items: center;
}

        
        
          
        
      

Centering with flexbox, method one:

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

        
        
          
        
      

Centering with flexbox, method two:

        
          
          .parent {  display: flex;}.child {  margin: auto;}
          .parent {
  display: flex;
}

.child {
  margin: auto;
}

        
        
          
        
      

Using margin and transform:

        
          
          .child {  margin-inline: auto;  margin-block-start: 50vh;  transform: translateY(-50%);}
          .child {
  margin-inline: auto;
  margin-block-start: 50vh;
  transform: translateY(-50%);
}

        
        
          
        
      

Absolute positioning when height is known:

        
          
          .child {  height: 200px;  margin-inline: auto;  inset-inline: 0;  /* Top margin 50% minus half the height */  inset-block-start: calc(50% - 100px);}
          .child {
  height: 200px;
  margin-inline: auto;
  inset-inline: 0;
  /* Top margin 50% minus half the height */
  inset-block-start: calc(50% - 100px);
}

        
        
          
        
      

Absolute positioning when height is unknown:

        
          
          .child {  margin-inline: auto;  inset-inline: 0;  inset-block-start: 50%;  transform: translateY(-50%);}
          .child {
  margin-inline: auto;
  inset-inline: 0;
  inset-block-start: 50%;
  transform: translateY(-50%);
}

        
        
          
        
      

Solution Breakdown

Before breaking down each of the solutions, let's understand the starter code. In all examples, we will set 100% height for <html> and <body> to stretch the page height.

Also, in all examples, logical properties are used wherever possible to keep the code modern.

As the block that we will be centering, we will use the tag <dialog>. It is currently customary to create popups using this.

Note that this element has absolute positioning by default. We will override the positioning to static so that it does not interfere. Also, note that the examples use the HTML tag <dialog> with explicitly set values for width and height. When applying to other tags, ensure that they have values set for width and height.

Starter code:

        
          
          <body class="parent">  <dialog class="child" open>    <h1>Hello, this is WebGuide!</h1>  </dialog></body>
          <body class="parent">
  <dialog class="child" open>
    <h1>Hello, this is WebGuide!</h1>
  </dialog>
</body>

        
        
          
        
      
        
          
          html {  height: 100vh;}body {  min-height: 100%;}dialog {  position: static;}
          html {
  height: 100vh;
}

body {
  min-height: 100%;
}

dialog {
  position: static;
}

        
        
          
        
      
Open demo in the new window

Grids

The most modern and elegant way to center an element is by using grids.

We make the parent — in this case, .parent — a grid container.

        
          
          .parent {  display: grid;}
          .parent {
  display: grid;
}

        
        
          
        
      

After this, we can use grid container properties to align nested elements along the vertical and horizontal axes:

        
          
          .parent {  display: grid;  justify-items: center;  align-items: center;}
          .parent {
  display: grid;
  justify-items: center;
  align-items: center;
}

        
        
          
        
      

Or use a shorthand to combine two properties into one:

        
          
          .parent {  display: grid;  place-items: center;}
          .parent {
  display: grid;
  place-items: center;
}

        
        
          
        
      
Open demo in the new window

Flexbox. First method

We use flexbox to center. There are two ways here. In the first case, we will set properties for the parent.

We make the parent a flex container:

        
          
          .parent {  display: flex;}
          .parent {
  display: flex;
}

        
        
          
        
      

We set properties to center along the vertical and horizontal axes:

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

        
        
          
        
      
Open demo in the new window

Flexbox. Second method

When the parent is a flex container, the child can have automatic margins on all sides.

        
          
          .parent {  display: flex;}.child {  margin: auto;}
          .parent {
  display: flex;
}

.child {
  margin: auto;
}

        
        
          
        
      
Open demo in the new window

Margin and Transformation

In this method, we use a combination of margins and transformation. To start, we will center the block along the horizontal axis with automatic margins, and push it down from the top by 50%:

        
          
          .child {  margin-inline: auto;  margin-block-start: 50vh;}
          .child {
  margin-inline: auto;
  margin-block-start: 50vh;
}

        
        
          
        
      
Open demo in the new window

The top margin is 50% of the screen height, but this shifts the element just below the center.

To position the element exactly in the center, we need to use the transform property with the translateY() function as its value.

        
          
          .child {  margin-inline: auto;  margin-block-start: 50vh;  transform: translateY(-50%);}
          .child {
  margin-inline: auto;
  margin-block-start: 50vh;
  transform: translateY(-50%);
}

        
        
          
        
      
Open demo in the new window

When transforming, percentages are calculated based on the actual size of the element being transformed. Therefore, our block rises exactly by half of its height.

Absolute Positioning with Known Height

Let's return absolute positioning to our dialog and try to center it in that state. Don't forget to set position: relative for the parent so that the child is positioned relative to the edges of the parent.

To start, let's break down the example when the element has a fixed height:

        
          
          .parent {  position: relative;}.child {  position: absolute;  height: 200px;}
          .parent {
  position: relative;
}

.child {
  position: absolute;
  height: 200px;
}

        
        
          
        
      

First, we need to set the coordinates of position measurement to zero on all four sides. We will use the logical property inset.

        
          
          .child {  position: absolute;  height: 200px;  inset: 0;}
          .child {
  position: absolute;
  height: 200px;
  inset: 0;
}

        
        
          
        
      

In reality, we only need zeros for the horizontal axis. For vertical alignment, we will use the familiar technique of automatic side margins.

For the vertical axis, we want to push the element down from the top by 50% minus half the height of the element. In our case, that is 125 pixels. We will use the function calc():

        
          
          .child {  position: absolute;  height: 250px;  margin-inline: auto;  inset-inline: 0;  inset-block-start: calc(50% - 125px);}
          .child {
  position: absolute;
  height: 250px;
  margin-inline: auto;
  inset-inline: 0;
  inset-block-start: calc(50% - 125px);
}

        
        
          
        
      
Open demo in the new window

Absolute Positioning without Known Height

In this variant, the height of the element is not fixed. This means we have nothing to subtract from 50% for the top margin. We use transform, which calculates percentages based on the element size.

        
          
          .child {  position: absolute;  margin-inline: auto;  inset-inline: 0;  inset-block-start: 50%;  transform: translateY(-50%);}
          .child {
  position: absolute;
  margin-inline: auto;
  inset-inline: 0;
  inset-block-start: 50%;
  transform: translateY(-50%);
}

        
        
          
        
      
Open demo in the new window