How to Style a Div to Be a Responsive Square

How to style a div to be a responsive square?

Works on almost all browsers.

You can try giving padding-bottom as a percentage.

<div style="height:0;width:20%;padding-bottom:20%;background-color:red">
<div>
Content goes here
</div>
</div>

The outer div is making a square and inner div contains the content. This solution worked for me many times.

Here's a jsfiddle

Responsive Square Divs Cross Browser Compatible

The main trick here is to make the div a square.

Normally one set a width, the height to 0 and a padding that equals to the width

.square {  height: 0;  width: 33%;  padding-bottom: 33%;  background: lightgray;}
<div class="square">  <div>    Content  </div></div>

Responsive Square in CSS

Of course you can !

CSS:

.wrapper{ display: grid;  grid-template-columns: repeat(4, 1fr);}
.wrapper > div { border: 1px solid black;position:relative;}
.wrapper > div:before {display: table; padding-top: 100%; content: '';}
.content{position: absolute;top:0; left:0; width:100%;height:100%;display:flex; justify-content:center; align-items:center;}

HTML:

<div class="wrapper">
<div><div class="content">1</div></div>
<div><div class="content">2</div></div>
<div><div class="content">3</div></div>
<div><div class="content">4</div></div>
</div>

Exemple in production : http://www.montblancnaturalresort.com

Snippet:

.wrapper {  display: grid;  grid-template-columns: repeat(4, 1fr);}
.wrapper>div { border: 1px solid black; position: relative;}
.wrapper>div:before { display: table; padding-top: 100%; content: '';}
.content { position: absolute; top: 0; left: 0; width: 100%; height: 100%; display: flex; justify-content: center; align-items: center;}
<div class="wrapper">  <div>    <div class="content">1</div>  </div>  <div>    <div class="content">2</div>  </div>  <div>    <div class="content">3</div>  </div>  <div>    <div class="content">4</div>  </div></div>

Grid of responsive squares

New solution (2022)

CSS has changed since this aswer was written. We now have several properties that can drasticaly simplify code for a square grid :

  • The grid property to handle the grid layout (MDN reference)
  • The aspect ratio property to handle the square aspect ratio of each grid item (MDN reference)
  • The object-fit property to handle image centering and wether they should cover the square or not (MDN reference)

Here is an example :

.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 2%;
}

.square {
aspect-ratio: 1/ 1;
display: flex;
align-items: center;
padding: 5%;
background-color: #1E1E1E;
color: #fff;
}

.square img {
width: 100%;
height: 100%;
object-fit: contain;
object-position: center;
}

.square.fullImg {
padding: 0;
}

.square.fullImg img {
object-fit: cover;
}
<div class="grid">
<div class="square">
<ul>This demo shows you can center multiple types of content :
<li>Text</li>
<li>Images</li>
<li>Lists</li>
<li>... (you can also do it with forms)</li>
</ul>
</div>
<div class="square">98%</div>
<div class="square">3.9/5</div>
<div class="square"><img src="https://farm3.staticflickr.com/2878/10944255073_973d2cd25c.jpg" /></div>
<div class="square"><img src="https://farm9.staticflickr.com/8461/8048823381_0fbc2d8efb.jpg" /></div>
<div class="square"><img class="rs" src="https://farm5.staticflickr.com/4144/5053682635_b348b24698.jpg" /></div>
<div class="square fullImg"><img src="https://farm9.staticflickr.com/8461/8048823381_0fbc2d8efb.jpg" /></div>
<div class="square fullImg"><img class="rs" src="https://farm5.staticflickr.com/4144/5053682635_b348b24698.jpg" /></div>
<div class="square fullImg"><img src="https://farm3.staticflickr.com/2878/10944255073_973d2cd25c.jpg" /></div>
</div>

Pure CSS Solution - Square Elements?

It is actually possible to achieve it with this neat trick i found at
this blog

#square {
width: 100%;
height: 0;
padding-bottom: 100%;
}

Hope that helps

Responsive square depending on content width

.wrapper-outer {  display: inline-block; /* make as wide as text */  vertical-align: top;  background-color: green;}
.wrapper-outer:nth-child(2) { background-color: tomato;}
.wrapper-outer:nth-child(3) { background-color: goldenrod;}
.wrapper-inner { height: 0; /* collapse the element */ padding: 50% 20px; /* top and bottom padding equal to half the width of parent; this gives us a height equal to the width of the parent */}
.text { transform: translateY(-50%); /* move text up to center; */}
<div class="wrapper-outer">  <div class="wrapper-inner">    <div class="text">Lorem ipsum!</div>  </div></div>
<div class="wrapper-outer"> <div class="wrapper-inner"> <div class="text">A</div> </div></div>
<div class="wrapper-outer"> <div class="wrapper-inner"> <div class="text">Lorem ipsum! Lorem ipsum! Lorem ipsum! Lorem ipsum!</div> </div></div>

How to make a clickable responsive square box with centered content?

Setting the parent .block to position: relative allows us to set .block > a to position: absolute, with dimensions that fill its parent; I only added 3 css rules, they're commented so you know which ones:

.block {
position: relative; /* change #1 */
width: 100%;
height: 0;
padding-bottom: 100%;
border: 2px solid #600;
}
.block a {
position: absolute; /* change #2 */
left: 0; right: 0; top: 0; bottom: 0; /* change #3 */
display: flex;
justify-content: center;
align-items: center;
background: #C00;
text-decoration: none;
}
.block span {
padding: 1em;
border: 2px solid #FFF;
text-align: center;
color: #FFF;
}

/* Demo only */
.row {
display: flex;
justify-content: space-between;
}
.column {
width: 20%;
}
<div class="row">
<div class="column">
<div class="block">
<a href="#">
<span>Download</span>
</a>
</div>
</div>
<div class="column">
<div class="block">
<a href="#">
<span>Download</span>
</a>
</div>
</div>
<div class="column">
<div class="block">
<a href="#">
<span>Download</span>
</a>
</div>
</div>
<div class="column">
<div class="block">
<a href="#">
<span>Download</span>
</a>
</div>
</div>
</div>

Create a perfect square div responsive

I think I've found my solution. Sorry, I just realized in my previous comment, it wasn't working for me because the body has a default margin.