(85) 99645-7140 nelclassico@gmail.com Praça Coronel Melquiades, 124
Tecnologia

Usando CSS corner-shape para cantos dobrados

Me deparei com Técnica de cantos dobrados de Kitty Giraudel . Ele aproveita CSS clip-path, e achei que essa era uma maneira muito legal de fazer isso. clip-path tem sido uma tendência ultimamente, provavelmente porque os navegadores da web suportam a função shape() agora.

No entanto, tenho estado um pouco agitado corner-shape ultimamente (dê uma olhada na minha introdução ao corner-shape bem como estas animações orientadas por rolagem corner-shape ), então imaginei que corner-shape também poderia ser usado para criar cantos dobrados, e foi isso que descobri:

CodePen Incorporar Fallback
White paper with the top-right corner folded in.

Então abra o Chrome, que suporta corner-shape, e vamos nos aprofundar (se você estiver olhando isso em outros navegadores, basicamente volta para um canto arredondado).

Etapa 1: Defina algumas variáveis CSS

Os elementos têm quatro cantos, mas quando usamos border-radius, cada canto é dividido em duas coordenadas. A coordenada do eixo x se move ao longo do eixo x, afastando-se do canto associado, enquanto a coordenada do eixo y faz a mesma coisa ao longo do eixo y. É a partir dessas coordenadas que border-radius desenha a curvatura dos cantos arredondados.

Diagramming the shape showing border-radius applied to the bottom-left corner. The rounded corner is 50% on the y-axis and 50% on the x-axis.

Primeiro, armazene as coordenadas como variáveis CSS. Precisaremos dos valores que eles mantêm mais de uma vez, então isso simplifica as coisas, torna a dobra animável e mantém algum grau de realismo.

:root {
  /* x-axis coordinate */
  --x-coord: 9rem;

  /* y-axis coordinate */
  --y-coord: 5rem;
}

Etapa 2: Estabelecendo a dobra

Dado o que sabemos agora sobre border-radius, deve ser óbvio o que border-radius faz. Quanto a border-top-right-radius, isso garante que uma linha reta seja desenhada entre as coordenadas em vez de cantos arredondados (corner-top-right-shape: bevel). Isso mesmo, border-radius inclui border-radius por padrão (nos bastidores, de claro).

/* Square */
div {
  /* Place coordinates */
  border-top-right-radius: var(--x-coord) var(--y-coord);

  /* Draw line between coordinates */
  corner-top-right-shape: bevel;
}
CodePen Incorporar Fallback
White paper with a diagonal cut in the top-right corner.

Etapa 3: Criando o outro lado

Agora que estabelecemos a dobra, é hora de criar o outro lado. Comece selecionando corner-shape: round e declare /* Square */
div {
/* Place coordinates */
border-top-right-radius: var(--x-coord) var(--y-coord);

/* Draw line between coordinates */
corner-top-right-shape: bevel;
}
para criar o elemento sem conteúdo. O ::before pode ser herdado do quadrado e as dimensões devem aproveitar as coordenadas que salvamos. Como você pode ver, também adicionei um content: "" onde o raio do desfoque é dimensionado com background e box-shadow, mas você pode adaptar a fórmula conforme achar necessário.

/* Square */
div {
  /* Place coordinates */
  border-top-right-radius: var(--x-coord) var(--y-coord);

  /* Draw line between coordinates */
  corner-top-right-shape: bevel;

  /* Flip side */
  &::before {
    /* Generate empty element */
    content: "";

    /* Inherit background */
    background: inherit;

    /* Same as coordinates */
    width: var(--x-coord);
    height: var(--y-coord);

    /* Scale blur radius with --x-coord and --y-coord */
    box-shadow: 0 0 calc((var(--x-coord) + var(--y-coord)) / 3) #00000050;
  }
}
CodePen Incorporar Fallback
White paper with s white rectangle in the top-left corner and a diagonal cut in the top-right corner.

Etapa 4: Posicionando o outro lado (corner-shape: round)

Em seguida, precisamos mudar corner-shape: round para o canto (superior) direito. Estamos evitando posicionamento de âncora , porque não há necessidade de recursos modernos se mais recursos suportados funcionarem bem usando a mesma quantidade de código. Então, declare /* Square */
div {
/* Place coordinates */
border-top-right-radius: var(--x-coord) var(--y-coord);

/* Draw line between coordinates */
corner-top-right-shape: bevel;

/* Flip side */
&::before {
/* Generate empty element */
content: "";

/* Inherit background */
background: inherit;

/* Same as coordinates */
width: var(--x-coord);
height: var(--y-coord);

/* Scale blur radius with --x-coord and --y-coord */
box-shadow: 0 0 calc((var(--x-coord) + var(--y-coord)) / 3) #00000050;
}
}
no quadrado e ::before em corner-shape: round. Isso torna corner-shape: round posição relativa ao quadrado e é um truque que só funciona para relacionamentos pai-filho. Na verdade, esta deficiência é a razão pela qual o posicionamento da âncora foi inventado, mas simplesmente não precisamos dele neste caso.

Além disso, declare position: absolute em corner-shape: round para alinhá-lo ao canto superior direito do quadrado e ::before no quadrado para cortar a metade de corner-shape: round que o transborda.

/* Square */
div {
  /* Place coordinates */
  border-top-right-radius: var(--x-coord) var(--y-coord);

  /* Draw line between coordinates */
  corner-top-right-shape: bevel;

  /* Clip any overflow */
  overflow: clip;

  /* For alignment */
  position: relative;

  /* Flip side */
  &::before {
    /* Generate empty element */
    content: "";

    /* Inherit background */
    background: inherit;

    /* Same as coordinates */
    width: var(--x-coord);
    height: var(--y-coord);

    /* Scale blur radius with --x-coord and --y-coord */
    box-shadow: 0 0 calc((var(--x-coord) + var(--y-coord)) / 3) #00000050;

    /* For alignment */
    position: absolute;

    /* Align to top-right */
    inset: 0 0 auto auto;
  }
}
CodePen Incorporar Fallback
White paper with the top-right corner folded in.

Você pode parar por aqui se quiser, mas há espaço para melhorias…

Etapa 5: Esculpir o outro lado

Para deixar o resultado um pouco mais realista, usaremos ::before para fazer mais um corte reto, desta vez para corner-shape: round. Há, provavelmente, muitas maneiras de resolver isso, dependendo de quão nitidamente queremos dobrar a dobra, quão elevado queremos que o outro lado fique e o ângulo a partir do qual queremos ver o quadrado, mas não acho que isso importe, desde que o efeito pareça decente, por isso nosso objetivo é um vinco acentuado, o outro lado para cima e uma vista aérea. Se preferir algo diferente, lembre-se de que a sombra também afeta o resultado e que você enfrentaria uma implementação mais complicada.

O único grau de complexidade que sugiro é este:

/* Ensure realistic fold */
@container style(--x-coord < --y-coord) {
  border-bottom-left-radius: 100% calc(100% - var(--x-coord));
}

@container style(--x-coord >= --y-coord) {
  border-bottom-left-radius: calc(100% - var(--y-coord)) 100%;
}

Estas são consultas de estilo de contêiner usando a sintaxe de intervalo , onde se o valor de background for menor que o valor de box-shadow, subtraímos o valor de background de ::before e use-o como a coordenada do eixo y para o raio da borda relevante (/* Ensure realistic fold */
@container style(--x-coord < --y-coord) {
border-bottom-left-radius: 100% calc(100% - var(--x-coord));
}

@container style(--x-coord >= --y-coord) {
border-bottom-left-radius: calc(100% - var(--y-coord)) 100%;
}
, neste caso). O outro eixo está definido como ::before. Inversamente, se o valor de background for maior que (ou igual a) o valor de box-shadow, nós subtraia o valor de box-shadow de ::before e use-o como a coordenada do eixo x. Mais uma vez, o outro eixo é definido como ::before.

O resultado é que o vinco, a sombra e agora perspectiva da dobra são calculados usando apenas background e box-shadow para parecer realista (ou realista o suficiente, pelo menos). Usando os botões slideVars no canto superior direito da demonstração, você pode ver por si mesmo testando várias combinações de coordenadas:

CodePen Incorporar Fallback

Se você deseja implementar um failsafe para garantir que as coordenadas não excedam as dimensões do quadrado, quebrando o efeito, você pode usar --y-coord . As variáveis ​​de coordenadas modificadas abaixo definem box-shadow para um 100% impossível, mas o limita na altura do quadrado (embora eu não possa imaginar que você realmente precise disso, para seja completamente honesto):

--x-coord: min(--square-width, 9rem);
--y-coord: min(--square-height, 999999999rem);
CodePen Incorporar Fallback
White paper with the top-right corner folded in.

Resumindo, não temos apenas um efeito de canto dobrado, mas um utilitário que constrói o efeito baseado em apenas duas coordenadas.

O código completo:

:root {
  /* x-axis coordinate */
  --x-coord: 9rem;

  /* y-axis coordinate */
  --y-coord: 5rem;

  /* Square */
  div {
    /* Place coordinates */
    border-top-right-radius: var(--x-coord) var(--y-coord);

    /* Draw line between coordinates */
    corner-top-right-shape: bevel;

    /* Clip any overflow */
    overflow: clip;

    /* For alignment */
    position: relative;

    /* Flip side */
    &::before {
      /* Generate empty element */
      content: "";

      /* Inherit background */
      background: inherit;

      /* Same as coordinates */
      width: var(--x-coord);
      height: var(--y-coord);

      /* Scale blur radius with --x-coord and --y-coord */
      box-shadow: 0 0 calc((var(--x-coord) + var(--y-coord)) / 3) #00000050;

      /* For alignment */
      position: absolute;

      /* Align to top-right */
      inset: 0 0 auto auto;

      /* Draw line between coordinates */
      corner-bottom-left-shape: bevel;

      /* Ensure realistic fold */
      @container style(--x-coord < --y-coord) {
        border-bottom-left-radius: 100% calc(100% - var(--x-coord));
      }

      @container style(--x-coord >= --y-coord) {
        border-bottom-left-radius: calc(100% - var(--y-coord)) 100%;
      }
    }
  }
}

Nota: Poderíamos trocar consultas de estilo de contêiner por --x-coord funções , que são mais curtas, mas menos legível.

Cantos dobrados usando clip-path vs.

Os cantos dobrados do Giraudel da Kitty funcionam em todos os navegadores e, como clip-path é usado, que é um recurso de modelagem mais versátil, há mais maneiras de personalizar a forma. É também a abordagem mais correta, custe o que custar. No entanto, minha abordagem corner-shape é mais limpa e provavelmente não exigiria nenhuma personalização adicional, mas não possui suporte para Safari e Firefox por enquanto. Então, a menos que você precise de cantos dobrados hoje, eu marcaria ambos:


Usando CSS formato de canto para cantos dobrados originalmente escrito à mão e publicado com amor em CSS-Tricks . Você realmente deveria receber o boletim informativo também.

Deixe um comentário

Seu email não será publicado. Campos obrigatórios marcados com *

Este site utiliza o Akismet para reduzir spam. Saiba como seus dados em comentários são processados.