Forma com um lado inclinado (responsivo)

90

Estou tentando criar uma forma como na imagem abaixo com uma borda inclinada em apenas um lado (por exemplo, o lado inferior) enquanto as outras bordas permanecem retas.

CSS div com um lado inclinado

Tentei usar o método de borda (o código é fornecido abaixo), mas as dimensões da minha forma são dinâmicas e, portanto, não posso usar esse método.

.shape {
    position: relative;
    height: 100px;
    width: 200px;
    background: tomato;
}
.shape:after {
    position: absolute;
    content: '';
    height: 0px;
    width: 0px;
    left: 0px;
    bottom: -100px;
    border-width: 50px 100px;
    border-style: solid;
    border-color: tomato tomato transparent transparent;
}
<div class="shape">
    Some content
</div>


Também tentei usar gradientes para o plano de fundo (como no código abaixo), mas fica confuso conforme as dimensões mudam. Você pode ver o que quero dizer ao passar o mouse sobre a forma no trecho abaixo.

Como posso criar essa forma com um lado inclinado e também ser capaz de oferecer suporte a tamanhos dinâmicos ?

atormentar
fonte

Respostas:

126

Existem muitas maneiras de criar a forma com uma borda inclinada apenas em um lado.

Os métodos a seguir não oferecem suporte a tamanhos dinâmicos, conforme já mencionado na pergunta:

  • Método de triângulo de borda com valores de pixel para border-width.
  • Gradientes lineares com a sintaxe de ângulo (como 45deg, 30deg etc).

Os métodos que podem suportar tamanhos dinâmicos são descritos abaixo.


Método 1 - SVG

( Compatibilidade do navegador )

O SVG pode ser usado para produzir a forma usando polygons ou paths. O snippet a seguir faz uso de polygon. Qualquer conteúdo de texto necessário pode ser posicionado no topo da forma.

Prós

  • O SVG é projetado para produzir gráficos escaláveis ​​e pode funcionar bem com todas as alterações de dimensão.
  • Bordas e efeito de foco podem ser obtidos com sobrecarga de codificação mínima.
  • Imagem ou plano de fundo gradiente também podem ser fornecidos para a forma.

Contras

  • O suporte do navegador é provavelmente a única desvantagem porque o IE8- não oferece suporte a SVG, mas isso pode ser atenuado usando bibliotecas como Raphael e também VML. Além disso, o suporte do navegador não é pior do que as outras opções.

Método 2 - fundo gradiente

( Compatibilidade do navegador )

Gradientes lineares ainda podem ser usados ​​para produzir a forma, mas não com os ângulos mencionados na pergunta. Temos que usar a to [side] [side]sintaxe (graças a vals ) em vez de especificar ângulos. Quando os lados são especificados, os ângulos de gradiente são ajustados automaticamente com base nas dimensões do contêiner.

Prós

  • A forma pode ser alcançada e mantida mesmo se as dimensões do recipiente forem dinâmicas.
  • O efeito de flutuação pode ser adicionado alterando a cor do gradiente.

Contras

  • O efeito de foco será acionado mesmo quando o cursor estiver fora da forma, mas dentro do contêiner.
  • Adicionar bordas exigiria manipulações de gradiente complicadas.
  • Os gradientes são conhecidos por produzirem cantos irregulares quando a largura (ou altura) é muito grande.
  • Planos de fundo de imagem não podem ser usados ​​na forma.

Método 3 - Transformações Skew

( Compatibilidade do navegador )

Neste método, um pseudo-elemento é adicionado, inclinado e posicionado de forma que pareça que uma das bordas está inclinada / inclinada. Se a borda superior ou inferior for inclinada, a inclinação deve ser ao longo do eixo Y, caso contrário a rotação deve ser ao longo do eixo X. O transform-origindeve ter o lado oposto ao lado inclinado.

Prós

  • A forma pode ser alcançada mesmo com bordas.
  • O efeito de pairar será restrito à forma.

Contras

  • Dimensões preciso aumentar proporcionalmente para a forma a ser mantida porque quando um elemento está inclinada, o seu deslocamento em aumentos do eixo Y como widthaumentos e vice-versa (tentar aumentar o widtha 200pxno fragmento). Você pode encontrar mais informações sobre isso aqui .

Método 4 - transformações de perspectiva

( Compatibilidade do navegador )

Neste método, o contêiner principal é girado ao longo do eixo X ou Y com um pouco de perspectiva. Definir o valor apropriado para transform-originproduziria uma borda inclinada em apenas um lado.

Se o lado superior ou inferior estiver inclinado, a rotação deve ser ao longo do eixo Y, caso contrário, a rotação deve ser ao longo do eixo X. O transform-origindeve ter o lado oposto ao lado inclinado.

Prós

  • A forma pode ser alcançada com bordas.
  • As dimensões não precisam aumentar proporcionalmente para que a forma seja mantida.

Contras

  • O conteúdo também será girado e, portanto, eles precisam ser girados em sentido contrário para parecerem normais.
  • O posicionamento de texto será tedioso se as dimensões não forem estáticas.

Método 5 - caminho do clipe CSS

( Compatibilidade do navegador )

Neste método, o contêiner principal é recortado na forma necessária usando um polígono. Os pontos do polígono devem ser modificados dependendo do lado onde a borda inclinada é necessária.

Prós

  • A forma pode ser mantida mesmo quando o contêiner está sendo redimensionado dinamicamente.
  • O efeito de pairar será perfeitamente restrito dentro das bordas da forma.
  • A imagem também pode ser usada como plano de fundo para a forma.

Contras

  • O suporte do navegador é muito fraco no momento.
  • As bordas podem ser adicionadas colocando-se um elemento absolutamente posicionado no topo da forma e dando a ele o clipe necessário, mas além de um ponto, ele não se ajusta bem ao redimensionar dinamicamente.

Método 6 - Canvas

( Compatibilidade do navegador )

A tela também pode ser usada para produzir a forma desenhando caminhos. O snippet abaixo tem uma demonstração. Qualquer conteúdo de texto necessário pode ser posicionado no topo da forma.

Prós

  • A forma pode ser alcançada e mantida mesmo se as dimensões do recipiente forem dinâmicas. Bordas também podem ser adicionadas.
  • O efeito de flutuação pode ser restrito aos limites da forma usando o pointInpathmétodo.
  • Imagem ou plano de fundo gradiente também podem ser fornecidos para a forma.
  • Melhor escolha se efeitos de animação em tempo real são necessários, pois não requer manipulação DOM.

Contras

  • A tela é baseada em varredura e, portanto, as bordas em ângulo ficarão pixeladas ou borradas quando dimensionadas além de um ponto * .

* - Para evitar a pixelização, seria necessário redesenhar a forma sempre que a janela de visualização fosse redimensionada. Há um exemplo disso aqui, mas isso é uma sobrecarga.

atormentar
fonte
35

Tentei usar o método de borda, mas as dimensões da minha forma são dinâmicas e, portanto, não posso usar esse método.


Método 7 - Unidades de janela de visualização (Border Redux )

( Compatibilidade do navegador )

As unidades de viewport são uma grande inovação no CSS3. Embora você geralmente possa usar valores percentuais para dinamizar suas propriedades, você não pode fazer isso porborder-width s ( nem por font-sizes ).

Com unidades de janela de visualização da janela de visualização, você pode definir dinamicamente as larguras das bordas , junto com os tamanhos dos objetos, em comparação com a dimensão da janela de visualização.

Nota: os valores percentuais referem-se ao objeto pai, não à janela de visualização (área visível da janela).

Para testar o método, inicie o seguinte snippet Página inteira e redimensione-o horizontal e verticalmente.

.shape {
    position: relative;
    height: 20vh;
    width: 40vw;
    background: tomato;
}
.shape:after {
    position: absolute;
    content: '';
    left: 0px;
    right: 0px;
    top: 20vh;
    border-width: 10vh 20vw;
    border-style: solid;
    border-color: tomato tomato rgba(0,0,0,0) rgba(0,0,0,0);
}
<div class="shape">Some content</div>

Prós - (1) Tudo é dinâmico, a cobertura do navegador é ampla.

Contras - (1) Você deve prestar atenção à forma como o seu sistema operacional lida com a barra de rolagem com overflow: auto;.

Andrea Ligios
fonte
3
Parece irregular na versão mais recente do cromo.
Mr_Green
Verdade! Acho que os motores do navegador ainda precisam de algum tempo para processar isso sem problemas. O Firefox também tem esse problema ao usar essa técnica com pixels em vez de unidades de janela de exibição, mas é corrigível usando rgba (,,, 0) em vez de transparente. Felizmente, temos outras opções agora;)
Andrea Ligios
1

Minha solução é inspirada naquele chamado Método 7 - Unidades de janela de visualização de Andrea Ligios, acima nesta página.

Usei a unidade "horizontal" para a altura também ( height:10vw) para manter as proporções dadas no trapézio ao redimensionar a largura da janela de navegação. Poderíamos chamar este Método 7b - Largura da janela de visualização .

Além disso, usar dois divs aninhados , em vez de um e do :afterseletor, permite um melhor ajuste dos estilos de conteúdo de texto, na minha opinião (por exemplo text-align, etc.).

.dtrapz {
  position: relative;
  margin: 10px 40vw;
  width: 0;
  height: 10vw;
  border: none;
  border-right: 20vw solid #f22;
  border-bottom: 5vw solid transparent;
}

.dtcont {
  position: absolute;
  width: 20vw;
  height: 10vw;
  text-align: center;
  color: #fff;/* just aesthetic */
}
<div class="dtrapz">
  <div class="dtcont">Some content</div>
</div>

MattAllegro
fonte
@ Downvoter Hi! Deixe-me saber o que há de errado com a minha resposta, para que eu possa editar ou excluir, se isso fizer sentido. Não sou um especialista, mas me parece que isso poderia ser aplicado em muitas páginas, trabalhar com conteúdo de texto mais longo, dependendo apenas da largura :)
MattAllegro