Decorações de imagens sofisticadas: inteligência de dados PlatoBlockchain mágica de elemento único. Pesquisa vertical. Ai.

Decorações de imagem extravagantes: magia de elemento único

Como o título diz, vamos decorar imagens! Há vários outros artigos por aí que falam sobre isso, mas o que estamos cobrindo aqui é um pouco diferente porque é mais um desafio. O desafio? Decore uma imagem usando apenas o marca e nada mais.

Isso mesmo, sem marcação extra, sem divs e sem pseudo-elementos. Apenas uma etiqueta.

Parece difícil, certo? Mas até o final deste artigo — e dos outros que compõem esta pequena série — vou provar que o CSS é poderoso o suficiente para nos dar ótimos e impressionantes resultados apesar da limitação de trabalhar com um único elemento.

Série de decorações de imagens extravagantes

  • Magia de Elemento Único — Você está aqui
  • Máscaras e efeitos avançados de foco (chegando em 21 de outubro )
  • Contornos e Animações Complexas (chegando em 28 de outubro )

Vamos começar com nosso primeiro exemplo

Antes de mergulhar no código, vamos enumerar as possibilidades de estilizar um sem quaisquer elementos extras ou pseudo-elementos. Podemos usar border, box-shadow, outlineE, é claro, background. Pode parecer estranho adicionar um plano de fundo a uma imagem porque não podemos vê-la, pois ela estará por trás da imagem - mas o truque é criar espaço por aí a imagem usando padding e / ou border e então desenhe nosso plano de fundo dentro desse espaço.

Eu acho que você sabe o que vem a seguir desde que eu falei background, certo? Sim, gradientes! Todas as decorações que vamos fazer dependem de muitos gradientes. Se você já Me seguiu por um tempo, acho que isso provavelmente não é surpresa para você. 😁

Vamos voltar ao nosso primeiro exemplo:

img {
  --s: 10px; /* control the size */
  padding: var(--s);
  border: calc(2 * var(--s)) solid #0000;
  outline: 1px solid #000;
  outline-offset: calc(-1 * var(--s));
  background: conic-gradient(from 90deg at 1px 1px, #0000 25%, #000 0);
}

estamos definindo padding e um transparente border usando a variável --s para criar um espaço em torno de nossa imagem igual a três vezes essa variável.

Por que estamos usando os dois padding e border em vez de um ou outro? Podemos usar apenas um deles, mas preciso dessa combinação para meu gradiente porque, por padrão, o valor inicial de background-clip is border-box e background-origin é igual a padding-box.

Aqui está uma ilustração passo a passo para entender a lógica:

Inicialmente, não temos bordas na imagem, então nosso gradiente criará dois segmentos com 1px de espessura. (Estou usando 3px nesta demonstração específica para que seja mais fácil de ver.) Adicionamos uma borda colorida e o gradiente ainda nos dá o mesmo resultado dentro da área de preenchimento (devido ao background-origin), mas se repete atrás da fronteira. Se tornarmos a cor da borda transparente, podemos usar a repetição e obter o quadro que desejamos.

A outline na demonstração tem um deslocamento negativo. Isso cria uma forma quadrada no topo do gradiente. É isso! Adicionamos uma bela decoração à nossa imagem usando um gradiente e um outline. Poderíamos ter usado mais gradientes! Mas sempre tento manter meu código o mais simples possível e descobri que adicionar um outline é melhor assim.

Aqui está uma solução somente de gradiente em que estou usando apenas padding para definir o espaço. Ainda o mesmo resultado, mas com uma sintaxe mais complexa.

Vamos tentar outra ideia:

Para este, peguei o exemplo anterior e removi o outline, e aplicou um clip-path para cortar o gradiente de cada lado. o clip-path value é um pouco verboso e confuso, mas aqui está uma ilustração para ver melhor seus pontos:

Decorações de imagem extravagantes: magia de elemento único

Acho que você entendeu a ideia principal. Vamos combinar fundos, contornos, recortes e algumas máscaras para obter diferentes tipos de decorações. Também vamos considerar algumas animações legais de hover como um bônus adicional! O que vimos até agora é apenas uma pequena visão geral do que está por vir!

A moldura apenas de canto

Este leva quatro gradientes. Cada gradiente cobre um canto e, ao passar o mouse, nós os expandimos para criar um quadro completo ao redor da imagem. Vamos dissecar o código para um dos gradientes:

--b: 5px; /* border thickness */
background: conic-gradient(from 90deg at top var(--b) left var(--b), #0000 90deg, darkblue 0) 0 0;
background-size: 50px 50px; 
background-repeat: no-repeat;

Vamos desenhar um gradiente com tamanho igual a 50px 50px e coloque-o no canto superior esquerdo (0 0). Para a configuração do gradiente, aqui está uma ilustração passo a passo mostrando como cheguei a esse resultado.

Nós tendemos a pensar que os gradientes são bons apenas para a transição entre duas cores. Mas, na realidade, podemos fazer muito mais com eles! Eles são especialmente úteis quando se trata de criar formas diferentes. O truque é garantir que tenhamos paradas fortes entre as cores — como no exemplo acima — em vez de transições suaves:

#0000 25%, darkblue 0

Isso está basicamente dizendo: “preencha o gradiente com uma cor transparente até 25% da área e, em seguida, preencha a área restante com darkblue.

Você pode estar coçando a cabeça sobre o 0 valor. É um pequeno truque para simplificar a sintaxe. Na realidade, devemos usar isso para fazer uma parada forte entre as cores:

#0000 25%, darkblue 25%

Isso é mais lógico! A cor transparente termina em 25% e darkblue começa exatamente onde termina a transparência, fazendo uma parada brusca. Se substituirmos o segundo por 0, o navegador fará o trabalho para nós, portanto, é uma maneira um pouco mais eficiente de fazer isso.

Em algum lugar em a especificação, diz:

se um parada de cor or dica de transição tiver uma posição menor que a posição especificada de qualquer parada de cor ou dica de transição antes dela na lista, defina sua posição para ser igual à maior posição especificada de qualquer parada de cor ou dica de transição antes dela.

0 é sempre menor que qualquer outro valor, então o navegador sempre o converterá para o maior valor que vem antes dele na declaração. No nosso caso, esse número é 25%.

Agora, aplicamos a mesma lógica a todos os cantos e terminamos com o seguinte código:

img {
  --b: 5px; /* border thickness */
  --c: #0000 90deg, darkblue 0; /* define the color here */
  padding: 10px;
  background:
    conic-gradient(from 90deg  at top    var(--b) left  var(--b), var(--c)) 0 0,
    conic-gradient(from 180deg at top    var(--b) right var(--b), var(--c)) 100% 0,
    conic-gradient(from 0deg   at bottom var(--b) left  var(--b), var(--c)) 0 100%,
    conic-gradient(from -90deg at bottom var(--b) right var(--b), var(--c)) 100% 100%;
  background-size: 50px 50px; /* adjust border length here */
  background-repeat: no-repeat;
}

Eu introduzi variáveis ​​CSS para evitar alguma redundância, pois todos os gradientes usam a mesma configuração de cores.

Para o efeito hover, tudo o que estou fazendo é aumentar o tamanho dos gradientes para criar o quadro completo:

img:hover {
  background-size: 51% 51%;
}

Sim, é 51% em vez de 50% — que cria uma pequena sobreposição e evita possíveis lacunas.

Vamos tentar outra ideia usando a mesma técnica:

Desta vez estamos usando apenas dois gradientes, mas com uma animação mais complexa. Primeiro, atualizamos a posição de cada gradiente e, em seguida, aumentamos seus tamanhos para criar o quadro completo. Também introduzi mais variáveis ​​para melhor controle sobre a cor, tamanho, espessura e até mesmo o espaço entre a imagem e o quadro.

img {
  --b: 8px;  /* border thickness*/
  --s: 60px; /* size of the corner*/
  --g: 14px; /* the gap*/
  --c: #EDC951; 

  padding: calc(var(--b) + var(--g));
  background-image:
    conic-gradient(from  90deg at top    var(--b) left  var(--b), #0000 25%, var(--c) 0),
    conic-gradient(from -90deg at bottom var(--b) right var(--b), #0000 25%, var(--c) 0);
  background-position:
    var(--_p, 0%) var(--_p, 0%),
    calc(100% - var(--_p, 0%)) calc(100% - var(--_p, 0%));
  background-size: var(--s) var(--s);
  background-repeat: no-repeat;
  transition: 
    background-position .3s var(--_i,.3s), 
    background-size .3s calc(.3s - var(--_i, .3s));
}
img:hover {
  background-size: calc(100% - var(--g)) calc(100% - var(--g));
  --_p: calc(var(--g) / 2);
  --_i: 0s;
}

Por que o --_i e --_p variáveis ​​têm um sublinhado em seu nome? Os sublinhados fazem parte de uma convenção de nomenclatura que uso para considerar variáveis ​​“internas” usadas para otimizar o código. Eles não são nada de especial, mas eu quero fazer a diferença entre as variáveis ​​que ajustamos para controlar o quadro (como --b, --c, etc.) e os que uso para tornar o código mais curto.

O código pode parecer confuso e não é fácil de entender, mas escrevi um série de três partes onde detalho tal técnica. Eu recomendo ler pelo menos o primeiro artigo para entender como cheguei ao código acima.

Aqui está uma ilustração para entender melhor os diferentes valores:

Mostrando a mesma imagem de dois carros clássicos três vezes para ilustrar as variáveis ​​CSS usadas no código.
Decorações de imagem extravagantes: magia de elemento único

A revelação do quadro

Vamos tentar outro tipo de animação onde revelamos o quadro completo ao passar o mouse:

Legal certo? E você, se olhar de perto, notará que as linhas desaparecem na direção oposta ao sair do mouse, o que deixa o efeito ainda mais chique! Eu usei um efeito semelhante em um artigo anterior.

Mas desta vez, em vez de cobrir todo o elemento, cobri apenas uma pequena parte definindo um height para obter algo assim:

Esta é a borda superior do nosso quadro. Repetimos o mesmo processo em cada lado da imagem e temos nosso efeito hover:

img {
  --b: 10px; /* the border thickness*/
  --g: 5px; /* the gap on hover */
  --c: #8A9B0F; 

  padding: calc(var(--g) + var(--b));
  --_g: no-repeat linear-gradient(var(--c) 0 0);
  background: 
    var(--_g) var(--_i, 0%) 0,
    var(--_g) 100% var(--_i, 0%),
    var(--_g) calc(100% - var(--_i, 0%)) 100%,
    var(--_g) 0 calc(100% - var(--_i, 0%));
  background-size: var(--_i, 0%) var(--b),var(--b) var(--_i, 0%);
  transition: .4s, background-position 0s;
  cursor: pointer;
}
img:hover {
  --_i: 100%;
}

Como você pode ver, estou aplicando o mesmo gradiente quatro vezes e cada um tem uma posição diferente para cobrir apenas um lado de cada vez.

Outro? Vamos lá!

Este parece um pouco complicado e realmente requer alguma imaginação para entender como dois gradientes cônicos estão realizando esse tipo de mágica. Aqui está uma demonstração para ilustrar um dos gradientes:

O pseudo-elemento simula o gradiente. Está inicialmente fora de vista e, ao passar o mouse, primeiro mudamos sua posição para obter a borda superior do quadro. Em seguida, aumentamos a altura para obter a borda certa. A forma do gradiente é semelhante às que usamos na última seção: dois segmentos para cobrir dois lados.

Mas por que fiz a largura do gradiente 200%? Você pensaria 100% seria o suficiente, certo?

100% deve ser suficiente, mas não poderei mover o gradiente como quero se mantiver sua largura igual a 100%. Essa é outra pequena peculiaridade relacionada a como background-position funciona. Eu cubro isso em um artigo anterior. eu também postou uma resposta no Stack Overflow lidar com isso. Eu sei que é muita leitura, mas realmente vale a pena o seu tempo.

Agora que explicamos a lógica de um gradiente, o segundo é fácil porque está fazendo exatamente a mesma coisa, mas cobrindo as bordas esquerda e inferior. Tudo o que temos a fazer é trocar alguns valores e pronto:

img {
  --c: #8A9B0F; /* the border color */
  --b: 10px; /* the border thickness*/
  --g: 5px;  /* the gap */

  padding: calc(var(--g) + var(--b));
  --_g: #0000 25%, var(--c) 0;
  background: 
    conic-gradient(from 180deg at top    var(--b) right var(--b), var(--_g))
     var(--_i, 200%) 0 / 200% var(--_i, var(--b))  no-repeat,
    conic-gradient(            at bottom var(--b) left  var(--b), var(--_g))
     0 var(--_i, 200%) / var(--_i, var(--b)) 200%  no-repeat;
  transition: .3s, background-position .3s .3s;
  cursor: pointer;
}
img:hover {
  --_i: 100%;
  transition: .3s, background-size .3s .3s;
}

Como você pode ver, ambos os gradientes são quase idênticos. Estou simplesmente trocando os valores do tamanho e da posição.

A rotação do quadro

Desta vez, não vamos desenhar um quadro em torno de nossa imagem, mas sim ajustar a aparência de uma existente.

Você provavelmente está perguntando como diabos eu sou capaz de transformar uma linha reta em uma linha angular. Não, a magia é diferente disso. Essa é apenas a ilusão que temos depois de combinar animações simples para quatro gradientes.

Vamos ver como é feita a animação do gradiente superior:

Estou simplesmente atualizando a posição de um gradiente de repetição. Nada extravagante ainda! Vamos fazer o mesmo para o lado direito:

Você está começando a ver o truque? Ambos os gradientes se cruzam no canto para criar a ilusão de que a linha reta é alterada para um ângulo. Vamos remover o contorno e ocultar o estouro para melhor visualizá-lo:

Agora, adicionamos mais dois gradientes para cobrir as bordas restantes e pronto:

img {
  --g: 4px; /* the gap */
  --b: 12px; /* border thickness*/
  --c: #669706; /* the color */

  padding: calc(var(--g) + var(--b));
  --_c: #0000 0 25%, var(--c) 0 50%;
  --_g1: repeating-linear-gradient(90deg ,var(--_c)) repeat-x;
  --_g2: repeating-linear-gradient(180deg,var(--_c)) repeat-y;
  background:
    var(--_g1) var(--_p, 25%) 0, 
    var(--_g2) 0 var(--_p, 125%),
    var(--_g1) var(--_p, 125%) 100%, 
    var(--_g2) 100% var(--_p, 25%);
  background-size: 200% var(--b), var(--b) 200%;
  transition: .3s;
}
img:hover {
  --_p: 75%;
}

Se pegarmos este código e ajustá-lo ligeiramente, podemos obter outra animação legal:

Você pode descobrir a lógica neste exemplo? Essa é a sua lição de casa! O código pode parecer assustador, mas usa a mesma lógica dos exemplos anteriores que vimos. Tente isolar cada gradiente e imagine como ele se anima.

Resumindo

Isso é um monte de gradientes em um artigo!

Com certeza é e eu avisei! Mas se o desafio é decorar uma imagem sem elementos extras e pseudo-elementos, ficamos com poucas possibilidades e os gradientes são a opção mais poderosa.

Não se preocupe se você estiver um pouco perdido em algumas das explicações. Recomendo sempre alguns dos meus artigos antigos onde entro em maior detalhe com alguns dos conceitos que reciclámos para este desafio.

Vou deixar com uma última demonstração para mantê-lo até o próximo artigo desta série. Desta vez, estou usando radial-gradient() para criar outro efeito de foco engraçado. Vou deixar você dissecar o código para entender como ele funciona. Faça-me perguntas nos comentários se você ficar preso!

Série de decorações de imagens extravagantes

  • Magia de Elemento Único — Você está aqui
  • Máscaras e efeitos avançados de foco (chegando em 21 de outubro )
  • Contornos e Animações Complexas (chegando em 28 de outubro )

Carimbo de hora:

Mais de Truques CSS