¿Cómo distribuir uniformemente los elementos en un div uno al lado del otro?


82

Esto está destinado a un menú.
Por ejemplo, tengo un elemento div con 3 intervalos en él, todos los cuales tienen algún margen, ancho máximo y flotante (izquierda o derecha).
Se coloca comenzando desde el lado izquierdo y dice así:
[[span1][span2][span3] - lots of free space here].
Quiero emparejarlo así:
[[span1] - space - [span2] - space - [span3]]
¿Cómo puedo hacer esto usando CSS? Dudo un poco que no sea posible.
Tenga en cuenta que quiero que mantenga el mismo estilo cuando agregue o elimine un elemento del menú.
HTML:

<div id="menu">
    <span class="menuitem"></span>
    <span class="menuitem"></span>
    <span class="menuitem"></span>
</div>

CSS:

#menu {
    ...
    width:800px;
}
.menuitem {
    display:block;
    float:left;
    margin-left:25px;
    position:relative;
    min-height:35px;
    max-width:125px;
    padding-bottom:10px;
    text-align:center;
}

1
<span>no es un elemento de bloque, no debería aceptar widthpropiedad
Marek Sebera

¿Puede proporcionar el código real?
Blazemonger

Respuestas:


93

En los 'viejos tiempos', usaba una tabla y los elementos de su menú estaban espaciados uniformemente sin tener que indicar explícitamente el ancho para la cantidad de elementos.

Si no fuera por IE 6 y 7 (si eso le preocupa), puede hacer lo mismo en CSS.

<div class="demo">
    <span>Span 1</span>
    <span>Span 2</span>
    <span>Span 3</span>
</div>

CSS:

div.demo {
    display: table;
    width: 100%;
    table-layout: fixed;    /* For cells of equal size */
}
div.demo span {
    display: table-cell;
    text-align: center;
}

Sin tener que ajustar la cantidad de artículos.

Ejemplo sin table-layout:fixed: las celdas se distribuyen uniformemente en todo el ancho, pero no son necesariamente del mismo tamaño, ya que su ancho está determinado por su contenido.

Ejemplo con table-layout:fixed: las celdas tienen el mismo tamaño, independientemente de su contenido. (Gracias a @DavidHerse en los comentarios por esta adición).

Si desea que el primer y último elemento del menú se justifiquen a la izquierda y a la derecha, puede agregar el siguiente CSS:

div.demo span:first-child {
    text-align: left;
}
div.demo span:last-child {
    text-align: right;
}

3
Con este método, las células no se distribuyen uniformemente. Consulte jsfiddle.net/hcrzx . La celda del medio es más larga que las otras dos celdas.
Susam Pal

1
@Susam: Cierto, las celdas no son necesariamente del mismo tamaño , ya que el ancho de la celda está determinado por su contenido (lo mismo que con una tabla HTML). Sin embargo, todavía diría que pueden describirse como distribuidos uniformemente , ya que están distribuidos uniformemente (no necesariamente por igual) en todo el ancho del elemento principal, según su contenido. Si desea celdas de igual tamaño, independientemente de su contenido, apuesto a que necesitará una solución con script.
MrWhite

50

Puede utilizar justificar.

Esto es similar a las otras respuestas, excepto que los elementos de la izquierda y la derecha estarán en los bordes en lugar de estar igualmente espaciados - [a ... b ... c en lugar de .a..b..c.]

<div class="menu">
    <span>1</span>
    <span>2</span>
    <span>3</span>
</div>

<style>
.menu {text-align:justify;}
.menu:after { content:' '; display:inline-block; width: 100%; height: 0 }
.menu > span {display:inline-block} 
</style>

Un problema es que debes dejar espacios entre cada elemento. [Ver el violín.]

Hay dos razones para configurar los elementos del menú en bloque en línea:

  1. Si el elemento es por defecto un elemento de nivel de bloque (como un <li>), la pantalla debe configurarse en línea o bloque en línea para permanecer en la misma línea.
  2. Si el elemento tiene más de una palabra ( <span>click here</span>), cada palabra se distribuirá uniformemente cuando se establezca en línea, pero solo los elementos se distribuirán cuando se establezca en bloque en línea.

Ver el JSFiddle

EDITAR:
Ahora que flexbox tiene un amplio soporte (todos los que no son IE e IE 10+), hay una "mejor manera".
Suponiendo la misma estructura de elementos anterior, todo lo que necesita es:

<style>
    .menu { display: flex; justify-content: space-between; }
</style>

Si desea que los elementos exteriores también estén espaciados, simplemente cambie el espacio entre el espacio alrededor.
Ver el JSFiddle


22

Si alguien quiere probar un enfoque ligeramente diferente, puede usar FLEX.

HTML

<div class="test">
    <div>Div 1</div>
    <div>Div 2</div>
    <div>Div 3</div>
    <div>Div 4</div>
</div>

CSS

.test {
    display: flex;
    flex-flow: row wrap;
    justify-content: space-around;
}
.test > div {
    margin-top: 10px;
    padding: 20px;
    background-color: #FF0000;
}

Aquí está el violín: http://jsfiddle.net/ynemh3c2/ (Intente agregar / eliminar divs también)

Aquí es donde aprendí sobre esto: https://css-tricks.com/snippets/css/a-guide- to-flexbox /


10

justify-content: space-betweeny display: flexes todo lo que necesitábamos, ¡pero gracias a @Pratul por la inspiración!


Respuesta genial. Consejo: Úselo flex-wrap: wrappara envolver el contenido.
Suyash Gupta

8

Esta es la forma rápida y sencilla de hacerlo

<div>
    <span>Span 1</span>
    <span>Span 2</span>
    <span>Span 3</span>
</div>

css

div{
    width:100%;
}
span{
    display:inline-block;    
    width:33%;
    text-align:center;
}

Luego, ajusta el widthde la spans al número que tienes.

Ejemplo: http://jsfiddle.net/jasongennaro/wvJxD/


muuuuuuuuuuuuuuuuu… ¿no hay una manera fácil de ajustar automáticamente el ancho?
jurchiks

width: 33%;es lo más cercano posible, pero se basa en el contenedor principal, no en la cantidad de elementos secundarios. Si desea que se ajuste en función de los elementos secundarios (intervalo), probablemente necesite jugar con JavaScript.
Shauna

correcto @ Shauna. @jurchiks, podría calcular automáticamente los widths en función del número de spans, pero eso requeriría algunos js. Si su menú no cambia con frecuencia, ajustar el widthno debería ser un problema.
Jason Gennaro

@ josh.trow. Ha sido lento para mí todo el día.
Jason Gennaro

@Jason: ya lo hice (excepto en PHP; no conozco JS lo suficientemente bien, ¿tal vez alguien pueda enseñarme cómo hacer esto?). Se ve bien, pero los márgenes se vuelven un problema.
jurchiks

1

Solo necesita mostrar el div con id #menucomo un contenedor flexible como este:

#menu{
    width: 800px;
    display: flex;
    justify-content: space-between;
}

0

He logrado hacerlo con la siguiente combinación de CSS:

text-align: justify;
text-align-last: justify;
text-justify: inter-word;

0

.container {
  padding: 10px;
}
.parent {
  width: 100%;
  background: #7b7b7b;
  display: flex;
  justify-content: space-between;
  height: 4px;
}
.child {
  color: #fff;
  background: green;
  padding: 10px 10px;
  border-radius: 50%;
  position: relative;
  top: -8px;
}
<div class="container">
  <div class="parent">
    <span class="child"></span>
    <span class="child"></span>
    <span class="child"></span>
    <span class="child"></span>
    <span class="child"></span>
    <span class="child"></span>
    <span class="child"></span>
    <span class="child"></span>
    <span class="child"></span>
    <span class="child"></span>
  </div>
</div>


-1

Haga que todos los tramos utilicen elementos de bloque en línea. Cree un tramo de tramo vacío con un ancho del 100% debajo de la lista de tramos que contiene los elementos del menú. A continuación, haga que el div que contiene los intervalos text-align: justified. Esto obligaría a que los elementos del bloque en línea [los elementos de su menú] se distribuyeran uniformemente.

https://jsfiddle.net/freedawirl/bh0eadzz/3/

  <div id="container">

          <div class="social">
            <a href="#" target="_blank" aria-label="facebook-link">
            <img src="http://placehold.it/40x40">
            </a>
            <a href="#" target="_blank" aria-label="twitter-link">
                <img src="http://placehold.it/40x40">
            </a>
            <a href="#" target="_blank" aria-label="youtube-link">
                <img src="http://placehold.it/40x40">
            </a>
            <a href="#" target="_blank" aria-label="pinterest-link">
                 <img src="http://placehold.it/40x40">
            </a>
            <a href="#" target="_blank" aria-label="snapchat-link">
                <img src="http://placehold.it/40x40">
            </a>
            <a href="#" target="_blank" aria-label="blog-link">
                 <img src="http://placehold.it/40x40">
            </a>

            <a href="#" aria-label="phone-link">
                 <img src="http://placehold.it/40x40">
            </a>
            <span class="stretch"></span>
          </div>
             </div>
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.