html - visual - w3 flex box




Div interno com taxa quadrada e flexbox (4)

Esta questão já tem uma resposta aqui:

Estou tentando conseguir o seguinte:

Onde a caixa azul é de altura variável e a caixa amarela é sempre de altura 50% da caixa azul.

É bastante simples usando flex

<div style="display:flex;align-items:center">
    <div id="yellow" style="height:50%">
    </div>
</div>

O problema é que eu estou tentando manter a caixa interna de uma relação específica, neste caso quadrado. Como eu abordo isso?

Pontos bônus:

  • Como eu geralmente especifico uma proporção? Existe uma solução que funciona não apenas para 1: 1, mas também para qualquer x: y?
  • Como eu faria isso sem usar o flexbox enquanto potencialmente ainda visando a)?

Informação extra: A caixa azul é sempre mais larga do que superior, pense num botão.


Eu não acho que há uma maneira de definir a largura usando a altura (mesmo se pudermos fazer o oposto usando algum truque como preenchimento), mas uma idéia é confiar em uma imagem quadrada que você torna invisível para manter a proporção . Em seguida, o conteúdo deve ser posicionado:

#blue {
  display: flex;
  align-items: center;
  justify-content:center;
  height:80vh;
  background: blue;
}

#yellow {
  height: 50%;
  background: yellow;
  position:relative;
}
img {
 max-height:100%;
 visibility:hidden;
}
#yellow .content {
  position:absolute;
  top:0;
  right:0;
  left:0;
  bottom:0;
}
<div id="blue" >
  <div id="yellow" >
    <img src="https://picsum.photos/500/500?image=1069" >
    <div class="content">Some content here</div>
  </div>
</div>

Mas no caso de a altura do azul ser um valor fixo, é melhor confiar na variável CSS assim:

#blue {
  display: flex;
  align-items: center;
  justify-content:center;
  --h:80vh;
  height:var(--h);
  background: blue;
}

#yellow {
  height: calc(var(--h) / 2);
  width:calc(var(--h) / 2);
  background: yellow;
  position:relative;
}
<div id="blue" >
  <div id="yellow" >
    <div class="content">Some content here</div>
  </div>
</div>


Se você girar 90 graus, é possível :)

  • largura e altura variáveis ​​do pai (e proporção)
  • criança é sempre 50% mais alta que seu pai
  • e um quadrado

Isso vai surtir efeito para outros conteúdos, se quiser, por causa da transformação.

Codepen

.flex {
  display: table-cell; /* allows "vertical" centering (not possible with flex/grid here because of the padding-top trick on child) */
  width: 12rem;
  height: 20rem;
  vertical-align: middle; /* "vertical" centering */
  transform: rotate(90deg) translateY(-50%); /* vertical becomes horizontal */
  background-color: lightblue;
}

.flex.large {
  height: 35rem;
}

.item {
  width: 50%;
  height: 0;
  margin-left: 25%; /* "horizontal" centering */
  padding-top: 50%; /* padding-top trick for a square */
  background-color: lightyellow;
}
<div class="flex">
  <div class="item"></div>
</div>

<hr>

<div class="flex large">
  <div class="item"></div>
</div>


Uma resposta semelhante à fornecida por Temani Afif, mas usando um svg em vez de uma imagem (portanto, não há necessidade de uma solicitação extra).

Além disso, é mais fácil adaptá-lo a proporções arbitrárias

.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>


Veja se isso pode ajudá-lo

.outer {
    background-color: lightblue;
    height: 100px; /* Change as per your requirement */
    display: flex;
    align-items: center;
    justify-content: center;
    max-width: 200px; /* You can Remove this */
}
.inner {
    background-color: lightyellow;
    height: 50%;
    width: 50px;
}
<div style="" class="outer">

<div id="yellow" class="inner">
</div>

</div>





flexbox