Dobrando o Flat com CSS

Uma abordagem CSS pura que se dobra fora do painel plano.

Mahmoud Elmahdi Seg. 22 de jul · 4 min ler Demonstração

Neste artigo, criaremos um painel fora da tela com um efeito de dobra e movimento elástico do conteúdo interno.

Eu vi toneladas de demonstrações legais ao longo dos anos na internet que foram feitas com Canvas, Threejs e todas essas técnicas pesadas. Eu estou procurando uma maneira mais simples desde então!

Eu tive essa tarefa no outro dia para construir um painel de bate-papo para o projeto que estou trabalhando que aparece pressionando o botão "Enviar uma mensagem" no perfil do usuário para que os usuários possam se comunicar uns com os outros. Depois de obter a funcionalidade principal e trabalhar totalmente, com base em nosso fluxo de trabalho, tive que encaminhá-la para a equipe de QA após a conclusão para que eles começassem a testar! Neste caso, eu tive tempo suficiente para fazer com que o chat fosse um painel animado dobrável com menos esforço ????. Alguns momentos depois, após arranhar minha barba, decidi usar um pouco de polygon(...) transition CSS e de caminho de clipe polygon(...) para realizar esse recurso / tarefa.

Demonstração

Estou usando um clichê CRA nesta demo para criar um componente React . Mas você pode ficar com qualquer pilha que você esteja confortável.

Link de demonstração: https://elmahdim.github.io/OffScreenPanel/

Componente OffScreenPanel

 import React, {useState} de 'react'; 
import classNames de 'classnames';
importar propTypes de 'prop-types';
importar estilos de './OffScreenPanel.module.css'; export const OffScreenPanel = (props) => {
const [aberto, toggleVisibility] = useState (false);
toggle const = () => toggleVisibility (! open);
Retorna (
<div className = {classNames ('offScreenPanel', {
[styles.open]: aberto
})}>
<button type = "button" className = {styles.button} onClick = {toggle}>
....
</ button>
<div className = {styles.panel}>
<div className = {styles.body}> {open && props.children} </ div>
</ div>
<div role = "apresentação" className = {styles.overlay} onClick = {toggle} />
</ div>
);
};
OffScreenPanel.propTypes = {
crianças: propTypes.any,
};
exportar padrão OffScreenPanel;

O código acima representa um componente OffScreenPanel funcional que usa a folha de estilo de módulos Hooks e CSS .

HTML simples

Os principais elementos que precisamos para dobrar / desdobrar o nosso painel sem reagir.

 <div class = "offScreenPanel open"> 
<div class = "panel">
<div class = "body"> ... </ div>
</ div>
<div role = "presentation" class = "overlay"> </ div>
</ div>

A classe open é comutável (via JavaScript) no elemento offScreenPanel . Não possui estilos associados.

O elemento do panel é responsável por dobrar / desdobrar seu layout. Temos duas opções para conseguir este efeito: adicionar mais dois elementos extras ou usar um pseudo-elemento CSS!

Eu vou escolher a segunda opção que está usando o pseudo elemento ( ::before , ::after ). Isso torna nossa marcação mais limpa e com menos código HTML.

O conteúdo interno será envolvido pelo body do elemento.

Estilos

 / * 
* painel:
* está fora da tela (deslocamento à direita) por padrão
* /
.panel {
posição: fixa;
top: 0;
direita: 0;
largura: 450px;
fundo: 0;
índice z: 2;
transformar: translateX (450 px);
}
/ *
* painel:
* em aberto, definimos seu deslocamento horizontal como "0"
* /
.open .panel {
transformar: translateX (0);
transição: todos os 400ms de facilidade;
}
/ *
* painel - o elemento dobrável [[]]
* faça cada elemento com metade da largura do tamanho do pai (painel)
* /
.panel :: antes,
.panel :: after {
conteúdo: '';
posição: absoluta;
top: 0;
fundo: 0;
Largura: 225px;
transição: todos os 400 ms de facilidade;
}
/ *
* painel - o elemento dobrável []]
* /
.panel :: before {
caminho de clip: polígono (100% 10%, 100% 0, 100% 100%, 100% 90%);
esquerda: 0;
}
/ *
* painel - o elemento dobrável []]
* /
.panel :: after {
background: # f0f0f0 gradiente linear (à direita, # f7f7f7 0%, #fff 100%);
caminho de clip: polígono (100% 50%, 100% 0, 100% 100%, 100% 50%);
direita: 0;
}
/ *
* painel - o elemento dobrável []]
* /
.open .panel :: antes,
.open .panel :: after {
caminho de clipe: polígono (0 0, 100% 0, 100% 100%, 0 100%);
}
/ *
* painel - o elemento dobrável [[]
* dando ao painel esquerdo um livro de papel como plano de fundo,
* cinza claro e branco
* /
.open .panel :: before {
atraso de transição: 400ms;
background: # f0f0f0 gradiente linear (à direita, # f3f3f3 0%, # f1f1f1 48%, # f1f1f1 100%);
}
/ *
* corpo, uma linha fina centrada por padrão
* /
.body {
posição: absoluta;
top: 0;
direita: 0;
altura: 100%;
esquerda: 0;
background-color: #fff;
transição: todos os 300ms cúbico-bezier (0,22, 0,61, 0,36, 1);
z-index: 1;
trilho: polígono (50% 50%, 50% 50%, 50% 50%, 50% 50%);
}
/ *
* corpo, dobrado e cabe seu pai com em aberto
* /
.open .panel .body {
atraso de transição: 0,8s;
caminho de clipe: polígono (0 0, 100% 0, 100% 100%, 0% 100%);
}
/ *
* overlay, oculto por padrão. para sobrepor o conteúdo por trás
* e fecha o painel clicando fora
* /
.overlay {
cor de fundo: rgba (0, 0, 0, 0,2);
posição: fixa;
visibilidade: oculto;
top: 0;
direita: 0;
fundo: 0;
largura: 100%;
altura: 100%;
z-index: 1;
opacidade: 0;
}
/ *
* overlay, visível em aberto
* /
.open .panel + .overlay {
opacidade: 1;
visibilidade: visível;
transição: todos os 400ms de facilidade;
}

Aqui está como parece para os dois estados: padrão e aberto