Stop Using Position Absolute to Center Divs (Do This Instead)
<p data-path-to-node="3">Centering an element in CSS used to be one of the most frustrating tasks for web developers. Over the years, we have moved from complex hacks to elegant, one-line solutions. This article explores the "old way" of centering versus the modern, efficient approach using CSS Grid.</p>
<h2 data-path-to-node="4">The Old Way: Position Absolute and Transforms</h2>
<p data-path-to-node="5">Historically, the most common method to center an element involved setting the parent to <code data-path-to-node="5" data-index-in-node="89">relative</code> and the child to <code data-path-to-node="5" data-index-in-node="115">absolute</code>. You then had to manually offset the child and use a transform to pull it back to the true center [<a class="ng-star-inserted" href="http://www.youtube.com/watch?v=x2ey9uBgVmE&t=12" target="blank" rel="noopener" data-hveid="0" data-ved="0CAAQ4QMahcKEwjWounzciSAxUAAAAAHQAAAAAQTA">00:12</a>].</p>
<h3 data-path-to-node="6">The CSS Code:</h3>
<div class="code-block ng-tns-c1137244013-29 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" data-hveid="0" data-ved="0CAAQhtANahcKEwjWounzciSAxUAAAAAHQAAAAAQTQ">
<div class="code-block-decoration header-formatted gds-title-s ng-tns-c1137244013-29 ng-star-inserted"><span class="ng-tns-c1137244013-29">CSS</span>
<div class="buttons ng-tns-c1137244013-29 ng-star-inserted"> </div>
</div>
<div class="formatted-code-block-internal-container ng-tns-c1137244013-29">
<div class="animated-opacity ng-tns-c1137244013-29">
<pre class="ng-tns-c1137244013-29"><code class="code-container formatted ng-tns-c1137244013-29" role="text" data-test-id="code-content"><span class="hljs-selector-class">.parent</span> {
<span class="hljs-attribute">position</span>: relative;
<span class="hljs-attribute">height</span>: <span class="hljs-number">300px</span>;
<span class="hljs-attribute">background-color</span>: <span class="hljs-number">#f0f0f0</span>;
}
<span class="hljs-selector-class">.child</span> {
<span class="hljs-attribute">position</span>: absolute;
<span class="hljs-attribute">top</span>: <span class="hljs-number">50%</span>;
<span class="hljs-attribute">left</span>: <span class="hljs-number">50%</span>;
<span class="hljs-attribute">transform</span>: <span class="hljs-builtin">translate</span>(-<span class="hljs-number">50%</span>, -<span class="hljs-number">50%</span>);
<span class="hljs-attribute">padding</span>: <span class="hljs-number">20px</span>;
<span class="hljs-attribute">background-color</span>: <span class="hljs-number">#3498db</span>;
<span class="hljs-attribute">color</span>: white;
}
</code></pre>
</div>
</div>
</div>
<p data-path-to-node="8">While effective, this method requires several lines of code and depends on the parent having a specific position property [<a class="ng-star-inserted" href="http://www.youtube.com/watch?v=x2ey9uBgVmE&t=53" target="blank" rel="noopener" data-hveid="0" data-ved="0CAAQ4QMahcKEwjWounzciSAxUAAAAAHQAAAAAQTg">00:53</a>].</p>
<h2 data-path-to-node="9">The Modern Way: CSS Grid</h2>
<p data-path-to-node="10">The newest and fastest way to center items is by using <strong data-path-to-node="10" data-index-in-node="55">CSS Grid</strong>. This method reduces the logic to just two primary properties on the parent container, eliminating the need for any CSS on the child element itself [<a class="ng-star-inserted" href="http://www.youtube.com/watch?v=x2ey9uBgVmE&t=80" target="blank" rel="noopener" data-hveid="0" data-ved="0CAAQ4QMahcKEwjWounzciSAxUAAAAAHQAAAAAQTw">01:20</a>].</p>
<h3 data-path-to-node="11">The CSS Code:</h3>
<div class="code-block ng-tns-c1137244013-30 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" data-hveid="0" data-ved="0CAAQhtANahcKEwjWounzciSAxUAAAAAHQAAAAAQUA">
<div class="code-block-decoration header-formatted gds-title-s ng-tns-c1137244013-30 ng-star-inserted"><span class="ng-tns-c1137244013-30">CSS</span>
<div class="buttons ng-tns-c1137244013-30 ng-star-inserted"> </div>
</div>
<div class="formatted-code-block-internal-container ng-tns-c1137244013-30">
<div class="animated-opacity ng-tns-c1137244013-30">
<pre class="ng-tns-c1137244013-30"><code class="code-container formatted ng-tns-c1137244013-30" role="text" data-test-id="code-content"><span class="hljs-selector-class">.parent-grid</span> {
<span class="hljs-attribute">display</span>: grid;
place-items: center;
<span class="hljs-attribute">height</span>: <span class="hljs-number">300px</span>; <span class="hljs-comment">/ Required to see vertical centering /</span>
<span class="hljs-attribute">background-color</span>: <span class="hljs-number">#f0f0f0</span>;
}
<span class="hljs-selector-class">.child-grid</span> {
<span class="hljs-attribute">padding</span>: <span class="hljs-number">20px</span>;
<span class="hljs-attribute">background-color</span>: <span class="hljs-number">#2ecc71</span>;
<span class="hljs-attribute">color</span>: white;
}
</code></pre>
</div>
</div>
</div>
<p data-path-to-node="13">By using <code data-path-to-node="13" data-index-in-node="9">place-items: center</code>, you handle both horizontal and vertical centering simultaneously with a single line of code [<a class="ng-star-inserted" href="http://www.youtube.com/watch?v=x2ey9uBgVmE&t=93" target="blank" rel="noopener" data-hveid="0" data-ved="0CAAQ4QMahcKEwjWounzciSAxUAAAAAHQAAAAAQUQ">01:33</a>].</p>
<h2 data-path-to-node="14">Comparison HTML Output</h2>
<p data-path-to-node="15">Below is the HTML structure that demonstrates the difference in simplicity.</p>
<div class="code-block ng-tns-c1137244013-31 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" data-hveid="0" data-ved="0CAAQhtANahcKEwjWounzciSAxUAAAAAHQAAAAAQUg">
<div class="code-block-decoration header-formatted gds-title-s ng-tns-c1137244013-31 ng-star-inserted"><span class="ng-tns-c1137244013-31">HTML</span>
<div class="buttons ng-tns-c1137244013-31 ng-star-inserted"> </div>
</div>
<div class="formatted-code-block-internal-container ng-tns-c1137244013-31">
<div class="animated-opacity ng-tns-c1137244013-31">
<pre class="ng-tns-c1137244013-31"><code class="code-container formatted ng-tns-c1137244013-31" role="text" data-test-id="code-content"><span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"parent"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"child"</span>></span>Centered with Absolute<span class="hljs-tag"></<span class="hljs-name">div</span>></span>
<span class="hljs-tag"></<span class="hljs-name">div</span>></span>
<span class="hljs-tag"><<span class="hljs-name">br</span>></span>
<span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"parent-grid"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"child-grid"</span>></span>Centered with Grid<span class="hljs-tag"></<span class="hljs-name">div</span>></span>
<span class="hljs-tag"></<span class="hljs-name">div</span>></span>
</code></pre>
</div>
</div>
</div>
<h3 data-path-to-node="17">Key Takeaways:</h3>
<ul data-path-to-node="18">
<li>
<p data-path-to-node="18,0,0"><strong data-path-to-node="18,0,0" data-index-in-node="0">Position Absolute:</strong> Requires <code data-path-to-node="18,0,0" data-index-in-node="28">top: 50%</code>, <code data-path-to-node="18,0,0" data-index-in-node="38">left: 50%</code>, and a <code data-path-to-node="18,0,0" data-index-in-node="55">transform</code> [<a class="ng-star-inserted" href="http://www.youtube.com/watch?v=x2ey9uBgVmE&t=59" target="blank" rel="noopener" data-hveid="0" data-ved="0CAAQ4QMahcKEwjWounzciSAxUAAAAAHQAAAAAQUw">00:59</a>].</p>
</li>
<li>
<p data-path-to-node="18,1,0"><strong data-path-to-node="18,1,0" data-index-in-node="0">CSS Grid:</strong> Only requires <code data-path-to-node="18,1,0" data-index-in-node="24">display: grid</code> and <code data-path-to-node="18,1,0" data-index-in-node="42">place-items: center</code> [<a class="ng-star-inserted" href="http://www.youtube.com/watch?v=x2ey9uBgVmE&t=99" target="blank" rel="noopener" data-hveid="0" data-ved="0CAAQ4QMahcKEwjWounzciSAxUAAAAAHQAAAAAQVA">01:39</a>].</p>
</li>
<li>
<p data-path-to-node="18,2,0"><strong data-path-to-node="18,2,0" data-index-in-node="0">Cleanliness:</strong> Grid removes the need for extra "math" or offsets, making your stylesheets much easier to maintain [<a class="ng-star-inserted" href="http://www.youtube.com/watch?v=x2ey9uBgVmE&t=107" target="blank" rel="noopener" data-hveid="0" data-ved="0CAAQ4QMahcKEwjWounzciSAxUAAAAAHQAAAAAQVQ">01:47</a>].</p>
</li>
</ul>
<p data-path-to-node="19">For more quick CSS tips, check out the original video: <a class="ng-star-inserted" href="https://www.youtube.com/watch?v=x2ey9uBgVmE" target="blank" rel="noopener" data-hveid="0" data-ved="0CAAQ4QMahcKEwjWounzciSAxUAAAAAHQAAAAAQVg">Stop Using Position Absolute to Center Divs (Do This Instead)</a></p>
<p data-path-to-node="19"><iframe src="https://www.youtube.com/embed/x2ey9uBgVmE" width="560" height="314" allowfullscreen="allowfullscreen"></iframe></p>
HTML
<div class="parent">
<div class="child">Centered with Absolute</div>
</div>
<br>
<div class="parent-grid">
<div class="child-grid">Centered with Grid</div>
</div>CSS
.parent-grid {
display: grid;
place-items: center;
height: 300px; /* Required to see vertical centering */
background-color: #f0f0f0;
}
.child-grid {
padding: 20px;
background-color: #2ecc71;
color: white;
}