Maintain Width and Height of Rotated Square Divs in CSS Grid (Responsive Solution)

Maintain width and height of rotated square divs in CSS grid (responsive solution)

Since you are rotating the element 45deg, the width/height need to follow this formula: height = width = 50vh / cos(45deg) = 50vh / 0.707. You need to also adjust the transform-origin and add a small translation to correct the position:

.grid {  display: grid;  grid-template-columns: repeat(3, 1fr);  grid-column-gap: 1em;  grid-row-gap: 1em;  transform: translateY(-29%) rotate(45deg);  transform-origin:bottom left;  overflow: hidden;  width:calc(50vh/0.707);  height:calc(50vh/0.707);}
.grid>div { border: solid 1px red;}
body { margin: 0; overflow: hidden;}
<div class="grid">    <div>      box    </div>    <div>      box    </div>    <div>      box    </div>    <div>      box    </div>    <div>      box    </div>    <div>      box    </div>    <div>      box    </div>    <div>      box    </div>    <div>      box    </div>  </div>

How to make CSS grid container keep responsive square size?

I'd do the following:

  1. Make the grid width and height responsively sized - for this use this method (.container and &::after pseudo element)
  2. Make the grid itself follow the square width and height of the container (.grid-wrapper)
  3. Use a container for the images, so that the containers resize inside the grid (1st row = 2 col wide, 2nd row = 2x1 col) (.grid-box)
  4. Use absolute positioned images in the divs, so they actually cover the divs

HTML code:

<div class='container'>
<div class='grid-wrapper'>
<div class='grid'>
<div class="grid-box">
<img src="https://picsum.photos/200/300"></img>
</div>
<div class="grid-box">
<img src="https://picsum.photos/200/300"></img>
</div>
<div class="grid-box">
<img src="https://picsum.photos/200/300"></img>
</div>
</div>
</div>
</div>

SASS code:

$-gutter: 10px;
$-max-width: 600px;

* {
box-sizing: border-box;
}

.container {
position: relative;
max-width: $-max-width;
width: 100%;
background: #ffff00;

&::after {
content: "";
display: block;
padding-bottom: 100%;
}
}

.grid-wrapper {
position: absolute;
width: 100%;
height: 100%;
padding: $-gutter;
}

.grid {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
gap: $-gutter;
width: 100%;
height: 100%;

&-box {
position: relative;
width: 100%;
height: 100%;

&:first-child {
grid-column: 1 / span 2;
}
}

img {
position: absolute;
width: 100%;
height: 100%;
background-color: #000000;
object-fit: cover;
}
}

Here is a Fiddle demo: https://jsfiddle.net/robertp/uLfj1swm/

And a screenshot of how this solution renders:
Sample Image

Fit rotated square in parent square?

you can use position relative and absolute , & percentage to draw it

see the following :

.square {    width: 50%;    padding-top: 50%;     background:blue;     position: relative;     } .square-inner {          transform: rotate(45deg);        background:red;        height: 70%;        width: 70%;        margin:auto;       position: absolute;  top:15%;  left:15%;    }
<div class="square"><div class="square-inner">

</div>
</div>

How to make parent div follow the height of a 45 degree rotated child div

For maximum flexibility (no matter what size the green square has) - use javascript to calculate the new height by looking at this like a right triangle, and using the Pythagoras Theorem:

if the formula is:
a²+b²=c²

then:
c = √(a²+b²)

then just set the parent-container height with the value of c.

let $a = $('.child-diamond').width(),
$b = $('.child-diamond').height(),
$c = Math.sqrt((Math.pow($a, 2)) + (Math.pow($b, 2)));

$('.parent-container').height($c);

(example uses jQuery)
https://codepen.io/anon/pen/jgBaVR

Rotating div's, absolute positioning and responsive-ness

I figured out how to do this!

I've used these sources:
http://www.dwuser.com/education/content/creating-responsive-tiled-layout-with-pure-css/
How to vertically center a div for all browsers?

I had to apply multiple wrappers and by using padding-bottom I managed to get responsive squares.
JSfiddle: http://jsfiddle.net/ZC9et/

HTML:

<div class="outer"><div class="middle"><div class="wrap"> <!-- Open .wrap -->

<div class="box side left"><!-- Open .box -->
<a href="#" class="boxInner innerLeft"><!-- Open .boxInner -->
</a><!-- Close .boxInner -->
</div><!-- Close .box -->

<div class="box"><!-- Open .box -->
<a href="#" class="boxInner innerMiddle"><!-- Open .boxInner -->
</a><!-- Close .boxInner -->
</div><!-- Close .box -->

<div class="box side right"><!-- Open .box -->
<a href="#" class="boxInner innerRight"><!-- Open .boxInner -->
</a><!-- Close .boxInner -->
</div><!-- Close .box -->

</div></div></div><!-- Close .wrap -->

CSS:

body {
margin: 0;
padding: 0;
background-color:#1b1b1b;
}

.outer{
display: table;
position: absolute;
height: 100%;
width: 100%;
}
.middle{
display: table-cell;
vertical-align: middle;
}
.wrap {
margin: 10px;
margin-left: auto;
margin-right: auto;
height:100%;
overflow: hidden;

-webkit-box-align:center;
-webkit-box-pack:center;
display:-webkit-box;
}

.box {
float: left;
position: relative;
width: 24.45%;
padding-bottom: 24.45%;

margin:auto;

top:0;
bottom: 0;
left: 0;
right: 0;

-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-o-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
}

.side {
width: 17.57%;
padding-bottom: 17.57%;
}

.left{
left:-8%;
}

.right{
left:8%;
}

.boxInner {
position: absolute;
left: 10px;
right: 10px;
top: 10px;
bottom: 10px;
overflow: hidden;

background-size: cover;
background-repeat:no-repeat;
}

.innerLeft{
background-color:blue;
}
.innerMiddle{
background-color:blue;
}
.innerRight{
background-color:blue;
}

Responsive grid of squares within a responsive grid of squares

I believe your imbrication is not right.

You need a flex container with 9 flex child holding also 9 boxes. floating boxes will do also since your dealing with square boxes DEMO

* {  box-sizing: border-box;}body,.flex {  display: flex;  flex-wrap: wrap;}.flex,.flex>div {  border: solid 1px;  width: 33.33%;  text-align: center;}.flex > div:before {  display: inline-block;  padding-top: 100%;  content: '';  vertical-align: middle;}body {  width:50%;  min-width: 450px;  margin:auto;  font-size: calc(0.5vw + 10px); /* to hold here 3 letters, you can increase vw value for a single number */}/* resize here or let window do it */div:nth-child(odd){background:rgba(0,0,0,0.25)  }
<div class="flex">  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div></div><div class="flex">  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div></div><div class="flex">  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div></div><div class="flex">  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div></div><div class="flex">  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div></div><div class="flex">  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div></div><div class="flex">  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div></div><div class="flex">  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div></div><div class="flex">  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div>  <div>    sudo  </div></div>

Inner div with square ratio and flexbox

A similar answer to the one provided by Temani Afif, but using an svg instead of an image (so no need to the extra request).

Also, it's easier to adapt it to arbitrary aspect ratios

.container {  height: 150px;  background-color: lightblue;  display: flex;  align-items: center;  justify-content: center;  margin: 10px;}
.aspectRatio { display: grid; background-color: yellow; height: 50%;}.aspectRatio svg { height: 100%; border: solid 1px red; animation: resize 1s infinite;}.aspectRatio > * { grid-area: 1 / 1 / 2 / 2;}
@keyframes resize { from {height: 100%;} to {height: 99.9%;}}
<div class="container">  <div class="aspectRatio">    <svg viewBox="0 0 1 1"></svg>    <div class="inner">square</div>  </div></div><div class="container">  <div class="aspectRatio">    <svg viewBox="0 0 4 3"></svg>    <div class="inner">ratio 4/3</div>  </div></div>

CSS grid with biggest squares without overflow

viewport unit combined with min() can help you:

#board {
--s: min(
(100vw - 5*10px)/4, /* the width of square (5 gaps and 4 square in a column) */
(100vh - 50px - 4*10px)/3 /* the height of square (4 gaps, height of toolbar and 3 square in a row) */
); /* we take the smallest value and use for both width/height */

display: grid;
margin:10px;
grid-gap: 10px;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(3, 1fr);
}

#toolbar {
background-color: red;
height:50px;
}

.card {
width: var(--s);
height: var(--s);
justify-self: center;
border-style: solid;
background-color: yellow;
box-sizing:border-box;
}

body {
margin:0;
}
<div id="toolbar"></div>
<div id="board">
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
</div>


Related Topics



Leave a reply



Submit