Leaving div height equal to width using css only

Asked

Viewed 1,595 times

6

Let’s say I have 4 div, with the property width:25%. In a space of 1000px, this 25% would represent 250px.

<div style="width:1000px"></div>
    <div style="width:25%;"></div>
    <div style="width:25%;"></div>
    <div style="width:25%;"></div>
    <div style="width:25%;"></div>
</div>

Using css only, it would be possible to "capture" the width of the responsive div in pixels and apply this captured value to the property height.

It would be something like:

<div style="width:1000px"></div>
    <div style="width:25%; height: 250px"></div>
    <div style="width:25%; height: 250px"></div>
    <div style="width:25%; height: 250px"></div>
    <div style="width:25%; height: 250px"></div>
</div>

My question is only about css, if it is possible to do this using only css, because I know it is possible to achieve this goal using js.

4 answers

8


It has a very simple way for it one is using calc(), and flex and CSS variable. The other is the hake of padding and maintaining the Aspect-ratio in a more responsive way, because you will see that the padding-top which will create the height is relative to the width of the container

Technique with calc(), and flex and CSS variable

Note that I will declare a value in the variable --debug: ; in the case 1000px and then I’ll declare var(--debug) as width and in the height I’ll use the function calc() of CSS to split var(--debug) by 4, doing so calc(var(--debug) / 4).

Notice the Gif below that as I change the value of the variable --debug the width and proportionally the height tb is changing.

inserir a descrição da imagem aqui

So what we have is a value only that is declared in the variable, this variable I use as width and that same variable of width i divided by 4 in heigth.

inserir a descrição da imagem aqui

See I can still use one Media Queries to change the value of --debug and thus change the whole container proportionally changing only one value. You would have something like this CSS below. Also remembering that you can declare these variables directly in :root as you can read here What does -- specified in bootstrap css :root mean?

@media (max-width: 1000px) {
  .container {
    --debug: 768px;
  }
}
@media (max-width: 768px) {
  .container {
    --debug: 320px;
  }
}

inserir a descrição da imagem aqui

Follow the image code above (Display full page to see responsiveness):

  * {
    box-sizing: border-box;
  }

  .container {
    --debug: 1000px;
    width: var(--debug);
    height: calc(var(--debug) / 4);
    display: flex;
    margin: auto;
  }

.item {
  flex: 1;
  border: 1px solid #000;
}

@media (max-width: 1000px) {
  .container {
    --debug: 600px;
  }
}
@media (max-width: 600px) {
  .container {
    --debug: 480px;
  }
}
<div class="container">
  <div class="item">item no container</div>
  <div class="item">item no container</div>
  <div class="item">item no container</div>
  <div class="item">item no container</div>
</div>


Technique that leaves the Aspect-ratio of container using padding-top

Notice that I now have two containers, one .container and within it the container .pai who is the father of .item.

The padding-top is relative to the width of the element, so I have a first container no defined width and as a padding-top of 25%, that is to say 1/4 height of the element itself. For that padding not to push the internal content down I needed another container, the container .pai who is with position:absolute and has 100% of height and width of .container main that is his father.

inserir a descrição da imagem aqui

That one container .pai has display:flex and their children flex:1 to be divided equally into 4 portions of the .pai.

* {
  box-sizing: border-box;
}
.container {
  position: relative;
  /* overflow: auto; */
  border: 1px solid #f00;
  padding-top: 25%;
}
.pai {
  position: absolute;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;
  display: flex;
}
.item {
  flex:1;
  border: 1px solid #000;
}
<div class="container">
  <div class="pai">
      <div class="item">item no container</div>
      <div class="item">item no container</div>
      <div class="item">item no container</div>
      <div class="item">item no container</div>
  </div>
</div>

0

Unused flexbox, you can use float: left in the Ivs and overflow: auto in the container, using the technique of Aspect ratio 1:1 with padding-top of the same value as width, that is to say, 25%:

.boxes{
   overflow: auto;
}

.boxes div{
   width: 25%;
   padding-top: 25%;
   float: left;
}

/* abaixo é só para ilustração, não inclua no CSS */
.boxes div:nth-child(odd){
   background: #ddd;
}

.boxes div:nth-child(even){
   background: #f5f5f5;
}
<p>Parágrafo acima</p>
<div class="boxes">
   <div></div>
   <div></div>
   <div></div>
   <div></div>
</div>
<p>Parágrafo abaixo</p>

This way we have 4 Ivs with 25% of the screen (or container), one next to the other and with the same height.

If you want to add content in Ivs (text or image), you can insert spans inside the daughter Ivs, with absolute positioning and dimensions 100% width and height defined by the properties top, right, bottom, and left in 0:

.boxes{
   overflow: auto;
}

.boxes div{
   position: relative;
   width: 25%;
   padding-top: 25%;
   float: left;
}

.boxes div span{
   position: absolute;
   top: 0;
   left: 0;
   bottom: 0;
   right: 0;
   padding: 10px; /* OPCIONAL: espaçamento das bordas */
}

/* abaixo é só para ilustração, não inclua no CSS */
.boxes div:nth-child(odd){
   background: #ddd;
}

.boxes div:nth-child(even){
   background: #f5f5f5;
}
<p>Parágrafo acima</p>
<div class="boxes">
   <div>
      <span>Texto ou imagem</span>
   </div>
   <div>
      <span>Texto ou imagem</span>
   </div>
   <div>
      <span>Texto ou imagem</span>
   </div>
   <div>
      <span>Texto ou imagem</span>
   </div>
</div>
<p>Parágrafo abaixo</p>

If adding borders to the Ivs, add box-sizing: border-box so that they are applied within the limits of 25% of the Ivs, and on the outside. For example:

.boxes{
   overflow: auto;
}

.boxes div{
   position: relative;
   width: 25%;
   padding-top: 25%;
   float: left;
   border: 2px solid #444;
   box-sizing: border-box;
}

.boxes div span{
   position: absolute;
   top: 0;
   left: 0;
   bottom: 0;
   right: 0;
   padding: 10px;
}

/* abaixo é só para ilustração, não inclua no CSS */
.boxes div:nth-child(odd){
   background: #ddd;
}

.boxes div:nth-child(even){
   background: #f5f5f5;
}
<p>Parágrafo acima</p>
<div class="boxes">
   <div>
      <span>Texto ou imagem</span>
   </div>
   <div>
      <span>Texto ou imagem</span>
   </div>
   <div>
      <span>Texto ou imagem</span>
   </div>
   <div>
      <span>Texto ou imagem</span>
   </div>
</div>
<p>Parágrafo abaixo</p>

-2

If you know the container width in the unit of measurement vw, just use this value divided by 4 in the children, for example, if the container is the maximum screen size, the height will be 25vw, if the container is 80% of the screen (or 80 vw), the height will be 20vw, etc

This is because the value used by vw is the same regardless if used in height or width, as well as the vh and the vmin

body {
  width: 100vw;
  height: 100vh;
  margin: 0;
  padding: 0;
}
div.row {
  width: 80vw;
  display: block;
  margin: 0 10vw;
  padding: 0;
}
div.col {
  width: 20vw; /* ou 25% */
  height: 20vw; /* ou calc(80vw / 4) */
  display: block;
  float: left;
  background-color: darkblue;
  margin: 0;
  padding: 0;
  border: 1px solid darkred;
  box-sizing: border-box;
}
<div class="row">
  <div class="col"></div>
  <div class="col"></div>
  <div class="col"></div>
  <div class="col"></div>
</div>

-3

Hello, try this way and see if it solves your problem.

<div style="width:100px; height: 400px; background: #4a4a4a">
    <div style="width:25%; margin: 1px; padding-bottom: 25%; background: #fff"></div>
    <div style="width:25%; margin: 1px; padding-bottom: 25%; background: #fff"></div>
    <div style="width:25%; margin: 1px; padding-bottom: 25%; background: #fff"></div>
    <div style="width:25%; margin: 1px; padding-bottom: 25%; background: #fff"></div>
</div>

Browser other questions tagged

You are not signed in. Login or sign up in order to post.