Como alinhar texto com uma imagem diagonal

Publicados: 2022-02-16
texto da imagem diagonal

Um cliente da OSTraining pediu uma maneira de alinhar o texto ao lado de uma imagem diagonal, mantendo espaço entre os dois elementos.

Meu primeiro pensamento foi adicionar linhas de quebra em pontos específicos do texto, porém isso não funcionou porque o site era responsivo.

Depois de conversar com o cliente chegamos a uma solução mais elegante...

O caso de uso

Neste exemplo, o texto precisa ser alinhado à esquerda e a imagem à direita. O verdadeiro desafio aqui é que o texto não deve se sobrepor à imagem. O resultado que queremos é mostrado abaixo:

2

A solução

Podemos adicionar divs vazios flutuando à direita com valores de largura dinâmicos para forçar o texto a não sobrepor a imagem. Observe que neste exemplo a imagem é adicionada como plano de fundo com CSS.

1

O HTML

O HTML para este exemplo é assim:

 <div>    <div class="spacing"></div>    <div class="spacing"></div>    <div class="spacing"></div>    <div class="spacing"></div>    <div class="spacing"></div>    <div class="spacing"></div>    <div class="spacing"></div>    <div class="spacing"></div>    <div class="spacing"></div>    <div class="spacing"></div>    <div class="spacing"></div>    <div class="spacing"></div>    <div class="spacing"></div>    <div class="spacing"></div>    <p>A buch of dummy text goes here...</p> </div>

Você pode notar as várias divs vazias com a classe de espaçamento . Esses elementos em combinação com algum CSS geram o espaçamento entre o texto e a imagem.

O número de divs de espaçamento é igual ao número de linhas de texto necessárias para preencher a altura da imagem. Neste exemplo, a imagem precisa ser coberta com 14 linhas.

O CSS

Vou dividir o CSS necessário em várias partes para uma melhor explicação.

 #container {  background-image: url(bg.png);  background-repeat: no-repeat;  background-position: right top;  background-size: 300px auto;  min-height: 300px; }

Define a imagem como plano de fundo com uma posição e tamanho específicos.

 #container p {  line-height: 22px;  font-family: Arial, "Helvetica Neue", Helvetica, sans-serif;  font-size: 14px; }

#container p seletor faz referência ao texto. É muito importante definir o tamanho da fonte e a altura da linha para calcular os valores de outras propriedades posteriormente.

 .spacing {  float: right;  clear: right;  height: 22px; }

Esta propriedade diz aos divs vazios para flutuar à direita. Observe que o valor para height é o mesmo que usamos para line-height nos parágrafos.

 .spacing:nth-child(1) {  width: 305px; } .spacing:nth-child(2) {  width: 283px; } .spacing:nth-child(3) {  width: 261px; } .spacing:nth-child(4) {  width: 239px; } .spacing:nth-child(5) {  width: 217px; } .spacing:nth-child(6) {  width: 195px; } .spacing:nth-child(7) {  width: 173px; } .spacing:nth-child(8) {  width: 151px; } .spacing:nth-child(9) {  width: 129px; } .spacing:nth-child(10) {  width: 107px; } .spacing:nth-child(11) {  width: 85px; } .spacing:nth-child(12) {  width: 63px; } .spacing:nth-child(13) {  width: 41px; } .spacing:nth-child(14) {  width: 19px; }

O código acima é a parte divertida que pode exigir o uso de uma calculadora.

O valor de largura escolhido para .spacing:nth-child(1) será aplicado ao primeiro div com a classe de espaçamento, da mesma forma que .spacing:nth-child(2) define uma largura um pouco menor e assim por diante até atingir o elemento de espaçamento número 14.

O motivo de definir valores dinâmicos de maior para menor para cada div vazio à direita possibilita manter o texto alinhado à esquerda sem sobrepor a imagem.

4

Dito isto, como podemos calcular a largura de cada uma dessas divs vazias? A resposta requer uma pequena fórmula baseada nos valores de:

  • line-height para o texto (22px no meu exemplo)
  • tamanho do plano de fundo (300px neste exemplo)

A largura da primeira div vazia é 305px, que é o valor da largura do plano de fundo definido mais 5 pixels extras que decidi incluir para evitar que o texto fique muito próximo da borda da imagem.

Suporte responsivo

Usando o código de exemplo, o design funcionará bem em qualquer tamanho de tela. Dê uma olhada na demonstração e redimensione o navegador para vê-lo em ação.

Veja uma demonstração

Bônus: MENOS

Uma alternativa para ir diretamente ao CSS é LESS. Temos um tutorial se você é novo no LESS.

Você pode gerar o mesmo resultado usando LESS para criar dinamicamente os vários valores de largura para cada div com classe de espaçamento facilmente sem se preocupar com matemática.

 @textHeight: 22px; @backgroundWidth: 300px; @extraSpacing: 5px; @initialWidth: @backgroundWidth + @extraSpacing; @textLines: @backgroundWidth / @textHeight;

Decida a altura do texto e a largura do plano de fundo através das variáveis.

 #container {    background-image: url(bg.png);    background-repeat: no-repeat;    background-position: right top;    background-size: @backgroundWidth auto;    min-height: @backgroundWidth; }

As propriedades do contêiner.

 #container p {    line-height: @textHeight;    font-family: Arial, "Helvetica Neue", Helvetica, sans-serif;    font-size: @textHeight - 8; } .spacing {    float: right;    clear: right;    height: @textHeight; }

As propriedades de texto e espaçamento são calculadas dinamicamente com base em algumas variáveis.

 .generate-spacing(@i, @end) when (@i <= @end) {    .spacing:nth-child(@{i}) {        width: @initialWidth - ((@i - 1) * @textHeight);    }    .generate-spacing((@i + 1), @end); } .generate-spacing(1, @textLines);

O loop que gera a largura dinâmica para todas as divs vazias.

Teste este código no Codepen