DÍA 1

¡Engañemos al CSS!

Este año he decidido no escribir sobre un tema concreto, sino hacer una lista de “trucos” que he ido recopilando a lo largo del año para hacer cosas que “supuestamente” no pueden hacerse o deberían hacerse de otro modo. Son soluciones me han hecho falta en algún momento y he tenido que “googlear” para encontrarlas. Si os ahorro algún que otro tiempo de “googleo”, ya merece la pena el artículo.


Como introducción decir que estos métodos no son, por supuesto, únicos, ni la manera más “correcta” o más rápida de hacer lo mismo, pero los que os dedicáis al desarrollo web sabéis que muchas veces, por las características del layout sobre el que estamos trabajando o el soporte que debemos dar a navegadores antiguos, no podemos utilizar las técnicas que nos gustarían y ahí empiezan nuestras pesadillas.

Además, aprender todas estas técnicas extrañas nos enseña un montón sin darnos cuenta.
Veréis que los grandes protagonistas van a ser los pseudo-elementos, si aún no estáis aprovechando todo el potencial que tienen, os aconsejo empezar leyendo el artículo que escribió Ricardo Prieto el año pasado, aquí os dejo el enlace para que lo hagáis.

Pseudo-elementos CSS que molan (o que al menos te salvan de un aprieto)

Comencemos.

1. Justificar una sola línea de texto

Por si no lo sabéis, la propiedad text-align: justify; solo puede utilizarse en párrafos con más de una línea, entonces, ¿qué pasa si quiero justificar una?

Veamos el ejemplo de un texto justificado, en el que quiero que el título también vaya justificado pero solo ocupa una línea.

justify_one_line

El HTML:

<div class="justify">
<h1>Soy un triste título</h1>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aspernatur quis quod enim,
maiores nesciunt veniam nulla aut quia soluta et dolorem, delectus deleniti at inventore
velit, corporis porro accusamus ducimus.
</div>

El CSS:

.justify{
  width: 400px;
  margin: 2em auto 0;
  background-color: salmon;
  font-family: sans-serif;
  color: white;
  text-align: justify;
  padding: 1em;
}

Vamos a engañar al CSS para que crea que tiene dos líneas y así justifique el título, para ello vamos a meter un pseudo-elemento :after (:before vale igual), que ocupe el 100% del ancho, de modo que ya tenemos la línea del texto, y la del :after.

h1{
  font-size: 2em;
  text-transform: uppercase;
  margin-bottom: 1em;
  text-align: justify;
  line-height: 1em;
  height: .5em;
 
  &::after{
    width: 100%;
    content:"";
    display: inline-block;
  }

Una cosa a tener en cuenta es que esta segunda línea ficticia que hemos metido, ocupa un alto, de modo que si no queréis ese espacio extra, tenéis que fijar el alto a la capa donde lo aplicáis.

Por otro lado, queridos niños, ya sabéis justificar los textos que queda muy feoooo… pero sí que me he encontrado con diseños de botones, por ejemplo, que van justificados, y esta es la solución que encontré.

Aquí tenéis el Codepen:

See the Pen Justificar una línea de texto by Diana (@diana_aceves) on CodePen.

2. Colocar dos elementos en los extremos de un contenedor, sin flotarlos y alineados verticalmente

Este truco es un derivado del anterior, vamos a utilizar la misma técnica para “justificar” elementos como si fueran texto, así se nos colocan rellenando el ancho completo del contenedor, uno a cada lado, como si estuvieran flotando a derecha e izquierda.

2.justify_header1

Como veis, he cogido el ejemplo de un header con un logo y un menú.

El HTML típico:

<header>
  <div id="logo">
   <a href="http://octuweb.com">
     <img src="http://octuweb.com/wp-content/themes/octuweb/img/octuweb_logow.svg">
    </a>
  </div>
  <ul class="menu">
    <li><a href="">Item 1</a></li>
    <li><a href="">Item 2</a></li>
    <li><a href="">Item 3</a></li>
    <li><a href="">Item 4</a></li>
    <li><a href="">Item 5</a></li>
  </ul>
</header>

El header va a ser el elemento al que ponemos text-align:justify, pero como ocupa una línea (logo a un lado y menú al otro) hay que usar el :after como en el caso anterior:

header{
  background-color: #EC6060;
  height: 8em;
  font-family: sans-serif;
  color: white;
  text-align: justify;
  padding: 2em 2%;
  width: 80%;
  max-width: 1200px;
  min-width: 650px;
  margin: 0 auto;
  &::after{
    width: 100%;
    content:"";
    display: inline-block;
  }
}

Ahora ponemos display: inline-block a los elementos que queremos justificar (para que se comporten como texto), en este caso, el logo y el menú.

#logo, .menu{
  display: inline-block;
  vertical-align: middle;
}

Además, si al logo le doy height:100%, la propiedad vertical-align: middle, hace que ambos se centren verticalmente respecto al header.

El código completo:

See the Pen Header con logo y menú justificados by Diana (@diana_aceves) on CodePen.

3. Menú con items equidistantes y al extremo del contenedor

Este rapidito porque también se usa el mismo :after que en los anteriores. El punto que tiene es que los elementos rellenan todo el ancho porque van justificados.

Con un display:table por ejemplo, si alineara al centro las celdas, los extremos quedarían separados del borde, no llegarían hasta el final.

Os pongo directamente el Codepen:

See the Pen Menu equidistante con text-align: justify by Diana (@diana_aceves) on CodePen.

4. Limitar número de líneas de texto y simular text-overflow: ellipsis

4.ellipsis

Hasta donde yo sé, no se puede utilizar text-overflow: ellipsis en párrafos multilínea. Existe una forma de hacerlo para webkit, pero evidentemente si no nos vale para el resto, pues no nos vale.

Podemos forzar ese comportamiento con javascript, pero también podemos simularlo de manera bastante apañada solo con CSS, con la ayuda de mis queridos pseudo-elementos.

Nuestro HTML:

<div class="container">
  <p class="ellipsis">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Obcaecati
culpa soluta nemo molestiae inventore, architecto a beatae magnam, at alias, aperiam atque
vitae autem maiores reprehenderit ex quae harum!</p>
</div>

Para que sea visible un número concreto de líneas, la fórmula es fácil:

altura del contenedor = nº líneas x alto de línea + overflow: hidden;

.ellipsis {
  line-height: 1.3em;
  max-height: 3.9em;
  overflow: hidden;
}

Pero claro, esto queda un poquito fatal, donde termina termina y se queda cortado.

4.ellipsis5

Vamos a incrustarle los “…” al final con un :after, y para asegurarnos de que no pisamos el texto, le damos un padding por la derecha, que disimule y nos permita poner los puntos al lado del final del texto.

See the Pen X número de líneas + ellipsis by Diana (@diana_aceves) on CodePen.

Os pongo una captura del inspector para que lo veáis:

4.ellipsis6

Este apaño queda perfecto en textos justificados (que ya sabéis niños que no hay que usar…), evidentemente en alineados de otra manera, pues depende de la suerte que tengáis con la longitud de las palabras finales.

text-align: left

4.ellipsis7


text-align: center

4.ellipsis8

No obstante si es un texto fijo, podéis ir controlando con media queries la posición aproximada de los puntos y que quede bastante bien.

Evidentemente si el texto es fijo y el ancho del contenedor también, problema resuelto, los colocáis donde queráis, pero hoy en día, es difícil y desde luego NADA RESPONSIVE.

5. Simular el comportamiento background-size: cover; si tenemos una etiqueta <img>

Todo se reduce a poner el min-height y min-width de la imagen al 100%, para asegurarnos de que siempre cubre todo el contenedor.

Después podemos colocarla como queramos dependiendo de la parte que preferimos perder al redimensionar, en top, bottom, left o right cero, o centrada como he preferido yo.

See the Pen Simular bg-size cover con etiqueta img by Diana (@diana_aceves) on CodePen.

6. CSS transition a height: auto

Si no os habéis encontrado con el caso de tener que mostrar un elemento mediante una transición, que pase de altura 0 a su altura automática, ya os tocará. Para los que sí que os habéis peleado con esta situación, sabéis que no se puede hacer, CSS transition no reconoce el alto final auto, lo que supone un problema.

La solución es utilizar como propiedad cambiante max-height, en vez de height, y darle como max-height final una altura mayor de la que sabemos que vamos a necesitar. De esta manera el elemento crece hasta su altura automática.

See the Pen CSS transition a height: auto by Diana (@diana_aceves) on CodePen.

Solo hay que tener cuidado con darle un max-height adecuado, sobre todo revisar si con el responsive no se nos queda corto.

Sed buenos.