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>
A grid layout with responsive squares
The padding-bottom
trick is the most used to accomplish that.
You can combine it with both Flexbox and CSS Grid, and since using percent for margin/padding gives inconsistent result for flex/grid items (on older browser versions, see edit note below), one can add an extra wrapper, or like here, using a pseudo, so the element with percent is not the flex/grid item.
Edit: Note, there's an update made to the specs., that now should give consistent result when used on flex/grid items. Be aware though, the issue still occurs on older versions.
Note, if you will add content to the content
element, it need to be position absolute to keep the square's aspect ratio.
Fiddle demo - Flexbox
Edit 2: In a comment I were asked how to have a centered text, so I added that in below snippet.
.square-container {
display: flex;
flex-wrap: wrap;
}
.square {
position: relative;
flex-basis: calc(33.333% - 10px);
margin: 5px;
border: 1px solid;
box-sizing: border-box;
}
.square::before {
content: '';
display: block;
padding-top: 100%;
}
.square .content {
position: absolute;
top: 0; left: 0;
height: 100%;
width: 100%;
display: flex; /* added for centered text */
justify-content: center; /* added for centered text */
align-items: center; /* added for centered text */
}
<div class="square-container">
<div class="square">
<div class="content">
<span>Some centered text</span>
</div>
</div>
<div class="square">
<div class="content spread">
</div>
</div>
<div class="square">
<div class="content column">
</div>
</div>
<div class="square">
<div class="content spread">
</div>
</div>
<div class="square">
<div class="content column">
</div>
</div>
</div>
How to make responsive squares for every element besides the last one, which has to have the same height as the others?
You need to filter the last-child and reset the vertical padding . codepen demo
possible fix to start from :
&:not(:last-child)::before {
content: "";
display: block;
padding-top: 100%;
}
&:last-child::before {
content: "";
display: block;
padding-top: 20%;/*here the values you want to reset */
}
if it is only about styling the padding, then
&::before {
content: "";
display: block;
padding-top: 100%;
}
&:last-child::before {
padding-top: 20%;
}
is plenty enough
:root {
/**
* [Changeable Settings]
* These are meant for updating the font and
* background colour later in JavaScript.
*/
--main-color: #415160;
--secondary-color: #fbfbf8;
--additional-color: #92928b;
--font-size: 1rem;
--line-height: 1.6rem;
--letter-spacing: 0rem;
--font-type: inherit;
/* FIXED SETTINGS */
/* [Colour Settings] */
--ink-blue: #415160;
--paper-white: #fbfbf8;
--drk-paper-white: #efefe7;
--brown-spot: #92928b;
/* [Font Settings] */
--xs-font-size: 0.6rem;
--sm-font-size: 0.8rem;
--reg-font-size: 1rem;
/* [Grid Settings] */
--grid-margin: 26px;
--grid-gutters: 9px;
--grid-column: 74px;
}
#font-settings {
margin-left: var(--grid-margin);
margin-right: var(--grid-margin);
background-color: var(--ink-blue);
padding: var(--reg-font-size);
border-radius: var(--reg-font-size);
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
}
#font-settings .square {
position: relative;
flex: 1 1 20%;
margin: var(--grid-gutters);
}
#font-settings .square::before {
content: "";
display: block;
padding-top: 100%;
}
#font-settings .square:last-child::before {
padding-top: calc(25% - var(--grid-gutters) );
}
#font-settings .square * {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
}
#font-settings .square *:hover {
box-shadow: 0px 0px 10px 10px rgba(0, 0, 0, 0.15);
}
<div id="font-settings">
<div class="square"><button>aaa</button></div>
<div class="square"><button>aaa</button></div>
<div class="square"><button>aaa</button></div>
<div class="square"><button>aaa</button></div>
<div class="square"><button>aaa</button></div>
<div class="square"><button>aaa</button></div>
<div class="square"><button>aaa</button></div>
<div class="square"><button>aaa</button></div>
<div class="square"><select>
<option>A</option>
<option>B</option>
<option>C</option>
</select></div>
</div>
Related Topics
How to Set Maximum Height for Table-Cell
Maxlength Ignored for Input Type="Number" in Chrome
Whatsapp Use Only HTML to Share Url Link by a Descriptive Text
Why Am I Seeing a 404 (Not Found) Error Failed to Load Favicon.Ico When Not Using This
How to Avoid Page Break Inside Table Row for Wkhtmltopdf
Make Container Shrink-To-Fit Child Elements as They Wrap
Angular 8 Material Dialog Close Button With X Top Right
How to Divide a Page in Three Vertical Sections
How to Make Sure This Stays Centered, Even When Zoomed Out or In
Wrapping Text Inside Input Type="Text" Element Html/Css
Bootstrap Row With Columns of Different Height
≪Button≫ Vs. ≪Input Type="Button" /≫. Which to Use
How to Set the Default Value For an HTML ≪Select≫ Element
Is It Valid to Replace Http:// With // in a ≪Script Src="Http://..."≫
Why Can't the ≪P≫ Tag Contain a ≪Div≫ Tag Inside It