<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[vieron.log]]></title>
  <link href="http://vieron.github.com/blog/atom.xml" rel="self"/>
  <link href="http://vieron.github.com/blog/"/>
  <updated>2011-10-10T16:34:43+02:00</updated>
  <id>http://vieron.github.com/blog/</id>
  <author>
    <name><![CDATA[vieron]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Columnas Justificadas en CSS]]></title>
    <link href="http://vieron.github.com/blog/blog/2011/09/28/columnas-justificadas-en-css/"/>
    <updated>2011-09-28T00:16:00+02:00</updated>
    <id>http://vieron.github.com/blog/blog/2011/09/28/columnas-justificadas-en-css</id>
    <content type="html"><![CDATA[<p>Hace unos meses, se me metió entre ceja y ceja que tenía que existir alguna manera cross-browser de conseguir columnas justificadas en CSS sin tener que dar anchos ni márgenes. La idea era tratar a las columnas como elementos inline (inline-block, en este caso) y aplicar un <code>text-align:justify</code> al contenedor.</p>

<h2>Primer problema</h2>

<p>El text-align: justify; justifica todo excepto la última línea (fila, en este caso). En la práctica estos son los dos casos que no se justifican:</p>

<ol>
<li>Si tienes una sola fila.</li>
</ol>


<p>  <iframe style="width: 100%; height: 150px" src="http://jsfiddle.net/R27GS/embedded/result,css,html/light/"></iframe></p>

<ol>
<li>La última fila, si tienes múltiples filas.</li>
</ol>


<p>  <iframe style="width: 100%; height: 220px" src="http://jsfiddle.net/Nmz6N/embedded/result,css,html/light/"></iframe></p>

<p>Empiezo a buscar y me entero que esta técnica se conoce como <a href="http://www.evolutioncomputing.co.uk/technical-1001.html">&#8220;Ben Justification&#8221;</a>. Encuentro diferentes
artículos para solucionarlo (aplicado a texto), pero lo hacen añadiendo marcado extra (<code>&lt;span&gt;&amp;nbsp;&lt;/span&gt;</code>) al final del bloque de texto, lo cual no me parece una opción.</p>

<p>En la <a href="http://www.w3.org/">w3c</a> ya se puede ver en el draft del módulo de texto de CSS3, la propiedad <a href="http://www.w3.org/TR/2011/WD-css3-text-20110901/#text-align-last">text-align-last</a>. Admite los valores <code>auto | start | end | left | right | center | justify </code> donde <code>justify</code> sería el que nos interesaría, pero por desgracia, a día de hoy esto no esta implementado en los navegadores.</p>

<p>Para Internet Explorer, de la versión 5 en adelante, tenemos la propiedad <code markdown="1"><a href="http://msdn.microsoft.com/en-us/library/ms531172%28v=vs.85%29.aspx">text-justify</a></code> con el valor <code>distribute-all-lines</code> que nos permite hacer justo lo que queremos.
Del 8 en adelante, la propiedad se usa como una extensión de CSS (con prefijo -ms-), me imagino que será porque esta propiedad aparece ya en las <a href="http://www.w3.org/TR/css3-text/#text-justify">specs de CSS3</a>.</p>

<p>En principio podríamos usarla así:<br /></p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='css'><span class='line'><span class="nt">-ms-text-justify</span><span class="o">:</span> <span class="nt">distribute-all-lines</span><span class="o">;</span> <span class="c">/* IE8+ */</span>
</span><span class='line'><span class="nt">text-justify</span><span class="o">:</span> <span class="nt">distribute-all-lines</span><span class="o">;</span> <span class="c">/* IE5+ */</span>
</span></code></pre></td></tr></table></div></figure>


<p>Por tanto tenemos cubierto todo el rango de versiones de Internet Explorer usadas actualmente, lo cual mola, pero nos quedan el resto (Chrome, Safari, Firefox&#8230;). Lo primero que pensé después de ver los artículos sobre &#8220;Ben Justification&#8221; fue que en los navegadores modernos ese marcado extra que se añadía, podría reemplazarse usando el pseudo-elemento <a href="http://www.w3.org/TR/CSS2/generate.html#before-after-content">:after</a>.</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='css'><span class='line'>  <span class="nc">.grid</span><span class="nd">:after</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">content</span><span class="o">:</span> <span class="s1">&#39;.&#39;</span><span class="p">;</span>
</span><span class='line'>    <span class="k">font-size</span><span class="o">:</span> <span class="m">1px</span><span class="p">;</span>
</span><span class='line'>    <span class="k">word-spacing</span><span class="o">:</span> <span class="m">100</span><span class="o">%</span><span class="p">;</span>
</span><span class='line'>    <span class="k">display</span><span class="o">:</span> <span class="o">-</span><span class="n">moz</span><span class="o">-</span><span class="k">inline</span><span class="o">-</span><span class="n">stack</span><span class="p">;</span>
</span><span class='line'>    <span class="k">display</span><span class="o">:</span> <span class="k">inline</span><span class="o">-</span><span class="k">block</span><span class="p">;</span>
</span><span class='line'>    <span class="k">width</span><span class="o">:</span> <span class="m">100</span><span class="o">%</span><span class="p">;</span>
</span><span class='line'>    <span class="k">visibility</span><span class="o">:</span> <span class="k">hidden</span><span class="p">;</span>
</span><span class='line'>  <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Conseguiríamos tener algo como esto:</p>

<iframe style="width: 100%; height: 220px" src="http://jsfiddle.net/S987X/embedded/result,css,html/light/"></iframe>


<br /><br />


<h2>Inconvenientes</h2>

<ol>
<li>Si hay desigualdad entre el número de elementos que entran en cada fila, el comportamiento no suele ser el necesitado.</li>
</ol>


<p>  <iframe style="width: 100%; height: 220px" src="http://jsfiddle.net/zVBYz/embedded/result,css,html/light/"></iframe></p>

<ol>
<li>El elemento generado con el <code>:after</code> hace que haya un espacio después de la última fila, que he conseguido reducir con un <code>line-height:0;</code>, pero no eliminar. Esto muchas veces no tiene porque ser un problema, pero si tienes un fondo de color como en el ejemplo, quizás si lo sea.</li>
</ol>


<h2>Solución final</h2>

<p>Como a partir de Internet Explorer 8 ya se soportan los pseudo-elementos <code>:after</code> y <code>:before</code>, he evitado usar el <code>-ms-text-justify</code>, para que no se apliquen ambas soluciones.</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
</pre></td><td class='code'><pre><code class='css'><span class='line'><span class="nc">.grid</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">text-align</span><span class="o">:</span><span class="k">justify</span><span class="p">;</span>
</span><span class='line'>  <span class="k">text</span><span class="o">-</span><span class="k">justify</span><span class="o">:</span> <span class="n">distribute</span><span class="o">-</span><span class="n">all</span><span class="o">-</span><span class="n">lines</span><span class="p">;</span>
</span><span class='line'>  <span class="k">line-height</span><span class="o">:</span><span class="m">0</span><span class="p">;</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="nc">.grid</span><span class="nd">:after</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">content</span><span class="o">:</span> <span class="s1">&#39;.&#39;</span><span class="p">;</span>
</span><span class='line'>  <span class="k">font-size</span><span class="o">:</span> <span class="m">1px</span><span class="p">;</span>
</span><span class='line'>  <span class="k">word-spacing</span><span class="o">:</span> <span class="m">100</span><span class="o">%</span><span class="p">;</span>
</span><span class='line'>  <span class="k">display</span><span class="o">:</span> <span class="o">-</span><span class="n">moz</span><span class="o">-</span><span class="k">inline</span><span class="o">-</span><span class="n">stack</span><span class="p">;</span>
</span><span class='line'>  <span class="k">display</span><span class="o">:</span> <span class="k">inline</span><span class="o">-</span><span class="k">block</span><span class="p">;</span>
</span><span class='line'>  <span class="k">width</span><span class="o">:</span> <span class="m">100</span><span class="o">%</span><span class="p">;</span>
</span><span class='line'>  <span class="k">visibility</span><span class="o">:</span> <span class="k">hidden</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="nc">.col</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">display</span><span class="o">:</span> <span class="o">-</span><span class="n">moz</span><span class="o">-</span><span class="k">inline</span><span class="o">-</span><span class="n">stack</span><span class="p">;</span>
</span><span class='line'>  <span class="k">display</span><span class="o">:</span> <span class="k">inline</span><span class="o">-</span><span class="k">block</span><span class="p">;</span>
</span><span class='line'>  <span class="o">*</span><span class="k">display</span><span class="o">:</span><span class="k">inline</span><span class="p">;</span>
</span><span class='line'>  <span class="k">vertical-align</span><span class="o">:</span><span class="k">top</span><span class="p">;</span>
</span><span class='line'>  <span class="n">zoom</span><span class="o">:</span><span class="m">1</span><span class="p">;</span>
</span><span class='line'>  <span class="k">text-align</span><span class="o">:</span><span class="k">left</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<h3>Para terminar</h3>

<ul>
<li>Es un patrón bastante común, y se puede usar para estructurar a todos los niveles.</li>
<li>La gran ventaja de este patrón es su flexibilidad, no tener que establecer anchos ni márgenes de separación entre elementos, es una gran win.</li>
<li>De momento esta es la mejor solución que he encontrado, pero seguro que se puede mejorar.</li>
</ul>


<h4>Referencias:</h4>

<ul>
<li><a href="http://www.evolutioncomputing.co.uk/technical-1001.html">http://www.evolutioncomputing.co.uk/technical-1001.html</a></li>
<li><a href="http://stackoverflow.com/questions/4771304/justify-the-last-line-of-a-div">http://stackoverflow.com/questions/4771304/justify-the-last-line-of-a-div</a></li>
<li><a href="http://www.cs.tut.fi/~jkorpela/www/justify.html">http://www.cs.tut.fi/~jkorpela/www/justify.html</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/ms534671.aspx">http://msdn.microsoft.com/en-us/library/ms534671.aspx</a></li>
<li><a href="http://archivist.incutio.com/viewlist/css-discuss/30191">http://archivist.incutio.com/viewlist/css-discuss/30191</a></li>
</ul>

]]></content>
  </entry>
  
</feed>

