Artigo original: CSS Shapes Explained: How to Draw a Circle, Triangle, and More Using Pure CSS

Antes de começarmos, saiba que, se você quiser mais conteúdo gratuito, porém em vídeo, o autor tem um canal no YouTube onde ele publica vídeos semanais sobre código para o front-end.

https://www.youtube.com/user/Weibenfalk

----------

Você é um novato em desenvolvimento para a web e em CSS? Já se perguntou como são feitas aquelas formas legais que você vê por toda a internet? Chega de se perguntar. Você veio ao lugar certo.

Abaixo, explicarei o básico na criação de formas com CSS. Existe muita coisa para dizer sobre o assunto! Portanto, eu não vou tratar de todas (longe disso) as ferramentas e formas, mas este artigo deve dar a você uma ideia básica de como são criadas as formas com CSS.

Algumas formas exigem mais "ajustes e truques" do que outras. Criar formas com CSS geralmente se resume a uma combinação dos atributos width, height, top, right, left, border, bottom, transform e de pseudoelementos como :before e :after. Também temos propriedades do CSS mais modernas para criar formas, como shape-outside e clip-path. Também falarei sobre elas mais abaixo.

Formas em CSS - o modo básico

Usando alguns truques em CSS, sempre foi possível criar formas básicas, como quadrados, círculos e triângulos usando as propriedades mais comuns. Vamos examinar algumas delas agora.

Quadriláteros e triângulos

Quadrados e retângulos são, provavelmente, as formas mais fáceis de se fazer. Por padrão, uma div é sempre um quadrado ou um retângulo.

Você define width (largura) e height (altura) conforme mostramos no código abaixo. Depois, é só uma questão de dar ao elemento uma background color (cor de fundo). Você pode usar todas as outras propriedades que quiser no elemento.

#quadrado {
    background: lightblue;
    width: 100px;
    height: 100px;
}
square
Um quadrado em CSS

Círculos

O círculo também é fácil de criar. Para criar um círculo, definimos o border-radius (raio da borda) do elemento. Isso criará cantos curvados no elemento.

Se os definirmos como 50%, criaremos um círculo. Se você definir uma width e uma height diferentes, obteremos uma figura oval.

#circulo {
    background: lightblue;
    border-radius: 50%;
    width: 100px;
    height: 100px;
}
circle
Um círculo em CSS

Triângulos

Triângulos são um pouco mais complicados. Temos de definir as bordas no elemento para que correspondam a um triângulo. Ao definir width e height como zero no elemento, a width real do elemento será a da borda.

Lembre-se de que os cantos das bordas em um elemento são diagonais a 45 graus uns dos outros. É por isso que esse método funciona para criar um triângulo. Ao definir uma das bordas com uma cor sólida e as outras bordas como transparentes, o elemento tomará a forma de um triângulo.

borders-1
As bordas do CSS têm cantos angulados
#triangulo {
    width: 0;
    height: 0;
    border-left: 40px solid transparent;
    border-right: 40px solid transparent;
    border-bottom: 80px solid lightblue;
}
triangle
Um triângulo em CSS

Se quiser que o triângulo/seta aponte em outra direção, você pode trocar os valores de borda correspondentes ao lado que você quer que seja visível. Você também pode rodar o elemento com a propriedade transform se quiser ser realmente elegante.

 #triangulo {
     width: 0;
     height: 0;
     border-top: 40px solid transparent;
     border-right: 80px solid lightblue;
     border-bottom: 40px solid transparent;
 }
triangle2
Outro triângulo em CSS

Certo – essa foi a introdução sobre as formas básicas com CSS. Existem, provavelmente, infinitas formas que você pode pensar em criar. Essas são apenas as fundamentais, mas, com um pouco de criatividade e determinação, você conseguirá muito apenas com as propriedades básicas do CSS.

Em alguns casos, com formas mais avançadas, também é uma boa ideia usar os pseudosseletores :after e :before (depois e antes, respectivamente). Isto está fora do escopo deste artigo, no entanto, já que minha intenção é tratar das questões mais básicas para deixá-lo pronto para seguir em frente.

Desvantagem

Existe uma grande desvantagem com a abordagem acima. Por exemplo, se você quiser que seu texto flua ao redor e envolva sua forma. Uma div de HTML regular, com segundo plano e bordas compondo a forma, não permitirá isso. O texto não se adaptará nem circundará sua forma. Em vez disso, ele ficará em volta da própria div (que é um quadrado ou um retângulo).

Abaixo vemos uma ilustração de um triângulo e de como ficaria o fluxo do texto.

textflow-bad

Por sorte, temos propriedades modernas de CSS para usar.

Formas em CSS - A outra maneira

Hoje em dia, temos uma propriedade chamada shape-outside para usar no CSS. Essa propriedade permite que você defina uma forma para que o texto a envolva e flua ao seu redor.

Junto dessa propriedade, temos algumas formas básicas:

inset()
circle()
ellipse()
polygon()

Aqui vai uma dica: Você também pode usar a propriedade clip-path. Você pode criar sua forma com ela da mesma maneira, mas ela não deixará o texto envolver sua forma do jeito que shape-outside permite.

O elemento em que vamos aplicar a forma com a propriedade shape-outside precisa ter a propriedade float. Ele também precisa ter width e height definidos. É realmente importante que você saiba disso!

Você pode ler mais a respeito do motivo aqui (texto em inglês). Abaixo, vemos um texto que extraí do link fornecido para o developer.mozilla.org.

A propriedade shape-outside é especificada usando os valores da lista abaixo, que define a área de flutuação dos elementos com float. A área de flutuação determina a forma ao redor da qual o conteúdo em linha (os elementos com float) ficará envolvido.

inset()

O tipo inset() pode ser usado para criar um retângulo/quadrado com um deslocamento opcional para o texto que o envolve. Ele permite fornecer valores para quanto você quer que o texto ao redor da forma entrecruze a forma.

Você pode especificar o deslocamento para que ele seja igual para todas as quatro direções assim: inset(20px). Também é possível fazer isso individualmente para cada direção: inset(20px 5px 30px 10px).

Você pode usar outras unidades para definir o deslocamentos, como, por exemplo, porcentagem. Os valores têm essa sequência: inset(acima direita abaixo esquerda).

Confira o exemplo do código abaixo. Especifiquei os valores de inset como 20px na parte superior, 5px à direita, 30px na parte inferior e 10px à esquerda. Se quiser que seu texto cerque seu quadrado ao invés disso, nem precisa usar inset(). Apenas defina o segundo plano (background) de sua div e o tamanho como sempre.

 #quadrado {
     float: left;
     width: 100px;
     height: 100px;
     shape-outside: inset(20px 5px 30px 10px);
     background: lightblue;
 }
inset
O texto é deslocado conforme os valores especificados. Neste caso, 20px acima, 5px à direita, 30px abaixo e 10px à esquerda.

Também é possível dar a inset() um segundo valor que especifica o border-radius do inset. Veja o exemplo abaixo:

 #quadrado {
     float: left;
     width: 100px;
     height: 100px;
     shape-outside: inset(20px 5px 30px 10px round 50px);
     background: lightblue;
 }
inset2
border-radius definido como 50px no inset

circle()

Aqui, um círculo é criado usando a propriedade shape-outside. Você também precisa aplicar um clip-path com a propriedade correspondente para que o círculo apareça.

A propriedade clip-path pode receber o mesmo valor que a propriedade shape-outside para darmos a ela a forma padrão de circle(), que usamos para shape-outside. Além disso, observe que apliquei uma margem de 20px no elemento aqui para dar ao texto algum espaço.

#circulo {
    float: left;
    width: 300px;
    height: 300px;
    margin: 20px;
    shape-outside: circle();
    clip-path: circle();
    background: lightblue;
}
circle-shape-margin-1
O texto flui ao redor da figura!

No exemplo acima, eu não especifico o raio do círculo. Isso ocorre porque eu quis que ele fosse do tamanho da div (300px). Se quiser especificar um tamanho diferente para o círculo, é possível fazer isso.

A propriedade circle() recebe dois valores. O primeiro é o raio e o segundo é a posição. Esses valores especificarão o centro do círculo.

No exemplo abaixo, defini radius (raio) como 50%. Em seguida, mudei o centro do círculo para 30%. Observe que a palavra "at" tem de ser usada entre os valores de radius e de position (posição).

Eu também especifiquei outro valor de position em clip-path. Isso cortará o círculo pela metade já que o movi para a posição zero.

 #circulo {
      float: left;
      width: 150px;
      height: 150px;
      margin: 20px;
      shape-outside: circle(50% at 30%);
      clip-path: circle(50% at 0%);
      background: lightblue;
    }
circle2

ellipse()

As elipses funcionam da mesma forma que os círculos, exceto pelo fato de criarem uma figura oval. Você pode definir os valores de X e de Y, assim: ellipse(25px  50px).

Da mesma forma que no círculo, ela também recebe um valor de position como o último valor.

   #elipse {
      float: left;
      width: 150px;
      height: 150px;
      margin: 20px;
      shape-outside: ellipse(20% 50%);
      clip-path: ellipse(20% 50%);
      background: lightblue;
    }
ellipse

polygon()

Um polígono é uma forma com vértices/coordenadas definidas. Abaixo, eu crio uma forma de "T", que é a primeira letra do meu nome. Eu começo nas coordenadas 0,0 e vou me movendo da esquerda para a direita para criar a forma de "T".

#poligono {
      float: left;
      width: 150px;
      height: 150px;
      margin: 0 20px;
      shape-outside: polygon(
        0 0,
        100% 0,
        100% 20%,
        60% 20%,
        60% 100%,
        40% 100%,
        40% 20%,
        0 20%
      );
      clip-path: polygon(
        0 0,
        100% 0,
        100% 20%,
        60% 20%,
        60% 100%,
        40% 100%,
        40% 20%,
        0 20%
      );
      background: lightblue;
    }
polygon_t

Imagens

Você também pode usar as imagens com segundo plano transparente para criar sua forma, como esta linda lua redonda abaixo.

Essa é uma imagem .png com um segundo plano transparente.

<img src="src/moon.png" id="moon" />
moon
#lua {
      float: left;
      width: 150px;
      height: 150px;
      shape-outside: url("./src/moon.png");
    }
moon2

É isso! Obrigado pela leitura.

Sobre o autor desse artigo

O nome do autor é Thomas Weibenfalk, um desenvolvedor da Suécia. Ele cria regularmente tutoriais gratuitos no canal dele no YouTube. Ele também tem alguns cursos premium sobre React e Gatsby. Visite-o em um desses links:

Twitter — @weibenfalk,
Weibenfalk no YouTube,
Site de cursos de Thomas Weibenfalk.