Estou tentando criar um aplicativo de bate-papo e, ao pressionar um botão, você pode ver os registros de data e hora das mensagens.
Meu timestamp sempre ocupa 200px de tamanho e o outro ocupa o restante.
Vamos chamar div1 para o registro de data e hora (200px) e div2 para as mensagens (ocupa o resto do espaço).
Tentei usar o translate no primeiro div1 e movê-lo e rapidamente percebi que o div2 não seria redimensionado automaticamente:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
*{
padding: 0px;
margin: 0px;
box-sizing: border-box;
}
.chat-container {
display: flex;
height: 50vh;
width: 50vw;
background-color: #f0f0f0;
}
#div1 {
background-color: #0004ff;
height: 100%;
width: 200px;
text-align: center;
position: relative;
left:-200px;
transition: left 1s;
}
#div2 {
background-color: #ff0000;
height: 100%;
text-align: center;
width: calc(100% - 200px); /* 100% - 200px or auto would work*/
}
</style>
</head>
<body>
<div class="chat-container">
<div id="div1">
<p>div1</p>
</div>
<div id="div2">
<p>div2</p>
</div>
</div>
<button id="button">animation</button>
<script>
let actived = false;
document.getElementById("button").addEventListener("click", function() {
const div1 = document.getElementById("div1");
const div2 = document.getElementById("div2");
div1.style.left = actived ? "-200px" : "0px";
actived = !actived;
});
</script>
</body>
</html>
Então tentei redimensionar o tamanho do div2, mas quando fiz isso, calc(100% - 200px)
não ficou do mesmo tamanho!!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
*{
padding: 0px;
margin: 0px;
box-sizing: border-box;
}
.chat-container {
display: flex;
height: 50vh;
width: 50vw;
background-color: #f0f0f0;
overflow: hidden;
}
#div1 {
background-color: #0004ff;
height: 100%;
width: 200px;
text-align: center;
position: relative;
left:-200px;
transition: left 1s;
}
#div2 {
background-color: #ff0000;
height: 100%;
text-align: center;
width: calc(100% - 200px); /* 100% - 200px or auto would work*/
position: relative;
transition: width 1s;
}
</style>
</head>
<body>
<div class="chat-container">
<div id="div1">
<p>div1</p>
</div>
<div id="div2">
<p>div2</p>
</div>
</div>
<button id="button">animation</button>
<script>
let actived = false;
document.getElementById("button").addEventListener("click", function() {
const div1 = document.getElementById("div1");
const div2 = document.getElementById("div2");
div1.style.left = actived ? "-200px" : "0px";
div2.style.width = actived ? "100%" : "calc(100% - 200px)";
actived = !actived;
});
</script>
</body>
</html>
Como pode 100%
o pai menos o tamanho do div1 não ser o resto? Estou tão confuso.
Por favor, diga-me qual método devo usar e por que 100% - 200px
não funciona.
Explicação
A diferença ao alternar é devido ao comportamento implícito
flex-shrink
(já que os elementos têm um padrão deflex-shrink: 1
em layouts flexíveis:Isto pode ser melhor demonstrado através de um exemplo.
Dizer
chat-container
é500px
amplo.As larguras intrínsecas dos elementos antes de qualquer contração de flexão ocorrer são:
200px
100% - 200px
= 500px - 200px
= 300px
Não há encolhimento, tudo se encaixa perfeitamente.
Clique no botão de animação duas vezes e então o div2
width
agora é100%
, assim:200px
100%
= 500px
Agora, div1 e div2 são mais largos que o contêiner, já que alterar
left
em div1 não remove o espaço que ele ocupa. Assim, os cálculos de flex shrinking acontecem da seguinte forma:Calcule as larguras excedentes dos nossos elementos filhos:
A proporção de div1:div2 é
2:5
, portanto alocamos esse200px
excedente entre eles da seguinte forma:200px ÷ 7 × 2
≈ 57px
200px ÷ 7 × 5
≈ 143px
Assim, as larguras finais são as seguintes:
143px
357px
Solução
Se você quiser realmente deslizar o div1 para dentro e para fora, você pode usar
margin
e deixar o div2 preencher o espaço naturalmente comflex-grow: 1
:Há muitas partes que entram em um aplicativo de bate-papo, então eu fiz um simples e animei as linhas conforme elas são feitas. Uma animação simples pode quebrar facilmente se o layout for complexo, elementos forem adicionados dinamicamente ou se houver rolagem envolvida, etc. Além disso, a primeira coluna tem 40% de largura em vez de 200px porque larguras absolutas não são responsivas. Os detalhes são comentados no exemplo. Visualizar no Full pagemodo.
A propósito, matematicamente
calc(100% - 200px)
deveria funcionar, mas se o pai tiver preenchimento à esquerda e/ou à direita ou se houver umagap
propriedade ou uma barra de rolagem etc., você precisa incluir isso na fórmula também.