2012-04-22 17 views
78

¿Cómo puedo alinear dos bloques en línea para que uno quede a la izquierda y el otro a la derecha en la misma línea? ¿Por qué es tan difícil? ¿Hay algo así como LaTeX's \ hfill que pueda consumir el espacio entre ellos para lograr esto?Alinee dos bloques en línea a izquierda y derecha en la misma línea

No quiero usar flotadores porque con bloques en línea puedo alinear las líneas de base. Y cuando la ventana es demasiado pequeña para ambos, con bloques en línea puedo simplemente cambiar el texto, alinearlo al centro y se centrarán uno encima del otro. El posicionamiento relativo (principal) + absoluto (elemento) tiene los mismos problemas que los flotantes.

El HTML5:

<header> 
    <h1>Title</h1> 
    <nav> 
     <a>A Link</a> 
     <a>Another Link</a> 
     <a>A Third Link</a> 
    </nav> 
</header> 

El css:

header { 
    //text-align: center; // will set in js when the nav overflows (i think) 
} 

h1 { 
    display: inline-block; 
    margin-top: 0.321em; 
} 

nav { 
    display: inline-block; 
    vertical-align: baseline; 
} 

Thery're uno al lado del otro, pero quiero que el nav a la derecha.

a diagram

+1

AFAIK la única forma de resolver esto es usar flotadores o posicionamiento absoluto. Puede lograr la misma posición de línea de base utilizando margin-top en el navegador. – powerbuoy

+0

Simplemente use margin-top y flotadores. No es posible hacer esto sin eso o con un posicionamiento absoluto. – jdhartley

+0

Use css media queries para cambiar el CSS dependiendo del tamaño de la ventana gráfica. Puedes usar tanto 'position: absolute' como' inline-block' – elclanrs

Respuesta

100

Editar: 3 años ha pasado desde que respondieron a esta pregunta y creo que se necesita una solución más moderna, aunque el actual hace lo :)

1. Flexbox

Es de lejos el más corto y más flexible. Aplicar display: flex; al contenedor principal y ajustar la colocación de sus hijos por justify-content: space-between; así:

.header { 
    display: flex; 
    justify-content: space-between; 
} 

puede verse en línea aquí - http://jsfiddle.net/skip405/NfeVh/1073/

Nota sin embargo, que es flexbox support IE10 y más recientes. Si necesita admitir IE 9 o una versión anterior, use la siguiente solución:

2. Puede utilizar la técnica text-align: justify aquí.

.header { 
    background: #ccc; 
    text-align: justify; 

    /* ie 7*/ 
    *width: 100%; 
    *-ms-text-justify: distribute-all-lines; 
    *text-justify: distribute-all-lines; 
} 
.header:after{ 
    content: ''; 
    display: inline-block; 
    width: 100%; 
    height: 0; 
    font-size:0; 
    line-height:0; 
} 

h1 { 
    display: inline-block; 
    margin-top: 0.321em; 

    /* ie 7*/ 
    *display: inline; 
    *zoom: 1; 
    *text-align: left; 
} 

.nav { 
    display: inline-block; 
    vertical-align: baseline; 

    /* ie 7*/ 
    *display: inline; 
    *zoom:1; 
    *text-align: right; 
} 

El ejemplo de trabajo se puede ver aquí: http://jsfiddle.net/skip405/NfeVh/4/.Este código funciona desde IE7 y superior

Si los elementos de bloque en línea en HTML no están separados por espacio, esta solución no funcionará - vea el ejemplo http://jsfiddle.net/NfeVh/1408/. Este podría ser un caso cuando inserta contenido con Javascript.

Si no nos importa IE7 simplemente omita las propiedades star-hack. El ejemplo de trabajo usando su marcado está aquí - http://jsfiddle.net/skip405/NfeVh/5/. Acabo de agregar la pieza header:after y justifiqué el contenido.

Con el fin de resolver el problema del espacio extra que se inserta con el pseudo-elemento after uno puede hacer un truco de establecer el font-size a 0 para el elemento padre y restablecer de nuevo a decir 14px para los elementos secundarios. El ejemplo de trabajo de este truco se puede ver aquí: http://jsfiddle.net/skip405/NfeVh/326/

+1

¿Hay alguna manera de evitar que la pancarta sea más alta? Me doy cuenta de cómo funciona esto, así que supongo que no. – mk12

+0

Esta solución es muy elegante, aunque la altura extra apesta, ¿no hay una solución ... a la solución? agrega exactamente 20 píxeles inútiles :-( ** edit **: posible solución, especifique la altura: NUMpx; en el contenedor, esto es muy malo por una serie de razones. – colthreepv

+1

Si está generando su contenido con javascript , tenga en cuenta que esta solución solo funciona si hay espacio en blanco entre los elementos. Necesitará insertar un nodo de texto entre los elementos izquierdo/derecho o ambos se pegarán a la izquierda. –

0

darle float: right y el flotador h1: izquierda y puso un elemento con clara: tanto después de ellos.

+7

"** No quiero usar floats **" – powerbuoy

+0

@powerbuoy funny, seleccionó la solución con flotadores al final, ¿no? –

+0

@Italy: Solo porque pensé que era la única forma posible, he cambiado mi respuesta aceptada. – mk12

1

Si ya está utilizando JavaScript para centrar las cosas cuando la pantalla es demasiado pequeña (según su comentario para su encabezado), ¿por qué no simplemente deshace flotantes/márgenes con JavaScript mientras lo usa y usa flotantes y márgenes? normalmente.

Incluso podría utilizar consultas de medios de CSS para reducir la cantidad de JavaScript que está utilizando.

+0

Supongo que realmente no estaba pensando en eso todavía, parecía que sería más fácil de esta manera. Pero aparentemente no. ¿Alguna pista sobre cómo me conectaría al navegador saltando a la siguiente línea desde javascript? – mk12

+0

¡Ahh, puedo usar consultas de medios para esto! Pensé que esos solo se usaban en el inicio, no en el cambio de tamaño. Gracias. – mk12

3

Si no desea utilizar flotadores, vas a tener que envolver su NAV:

<header> 
<h1>Title</h1> 
<div id="navWrap"> 
<nav> 
    <a>A Link</a> 
    <a>Another Link</a> 
    <a>A Third Link</a> 
</nav> 
</div> 
</header> 

... y añadir un poco de CSS más específico:

header { 
//text-align: center; // will set in js when the nav overflows (i think) 
width:960px;/*Change as needed*/ 
height:75px;/*Change as needed*/ 
} 

h1 { 
display: inline-block; 
margin-top: 0.321em; 
} 

#navWrap{ 
position:absolute; 
top:50px; /*Change as needed*/ 
right:0; 
} 

nav { 
display: inline-block; 
vertical-align: baseline; 
} 

Usted puede necesitar hacer un poco más, pero eso es un comienzo.

3

Aprovechando la respuesta de @ skip405, he hecho un mixin Sass para ello:

@mixin inline-block-lr($container,$left,$right){ 
    #{$container}{   
     text-align: justify; 

     &:after{ 
      content: ''; 
      display: inline-block; 
      width: 100%; 
      height: 0; 
      font-size:0; 
      line-height:0; 
     } 
    } 

    #{$left} { 
     display: inline-block; 
     vertical-align: middle; 
    } 

    #{$right} { 
     display: inline-block; 
     vertical-align: middle; 
    } 
} 

acepta 3 parámetros. El contenedor, el elemento izquierdo y el derecho. Por ejemplo, para adaptarse a la pregunta, se puede utilizar de esta manera:

@include inline-block-lr('header', 'h1', 'nav'); 
0

Creo que una posible solución para esto es utilizar display: table:

.header { 
    display: table; 
    width: 100%; 
    box-sizing: border-box; 
} 

.header > * { 
    display: table-cell; 
} 

.header > *:last-child { 
    text-align: right; 
} 

h1 { 
    font-size: 32px; 
} 

nav { 
    vertical-align: baseline; 
} 

jsFiddle: http://jsfiddle.net/yxxrnn7j/1/

0

Para ambos elementos usan

display: inline-block; 

para el elemento 'nav' use

float: right; 
Cuestiones relacionadas