Alinear dos bloques en línea a la izquierda y a la derecha en la misma línea

113

¿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 como \ hfill de LaTeX que pueda consumir el espacio entre ellos para lograr esto?

No quiero usar flotadores porque con bloques en línea puedo alinear las líneas base. Y cuando la ventana es demasiado pequeña para ambos, con los bloques en línea puedo simplemente cambiar la alineación del texto al centro y se centrarán uno encima del otro. El posicionamiento relativo (padre) + 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;
}

Están uno al lado del otro, pero quiero el navde la derecha.

un diagrama

mk12
fuente
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 usando margin-top en el navegador.
powerbuoy
Solo use margin-top y flotadores. No es posible hacer esto sin eso o un posicionamiento absoluto.
jdhartley
Use css media queries para cambiar el CSS según el tamaño de la ventana gráfica. Puede usar ambos position: absoluteyinline-block
elclanrs

Respuestas:

147

Editar: Han pasado 3 años desde que respondí esta pregunta y supongo que se necesita una solución más moderna, aunque la actual hace la cosa :)

1. Caja flexible

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

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

Se puede ver en línea aquí: http://jsfiddle.net/skip405/NfeVh/1073/

Sin embargo, tenga en cuenta que el soporte de flexbox es IE10 y más reciente. Si necesita admitir IE 9 o una versión anterior, use la siguiente solución:

2. Puedes usar la text-align: justifytécnica 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 con espacio, esta solución no funcionará; consulte 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 de star-hack. El ejemplo de trabajo que usa su marcado está aquí: http://jsfiddle.net/skip405/NfeVh/5/ . Solo agregué la header:afterparte y justifiqué el contenido.

Para resolver el problema del espacio extra que se inserta con el afterpseudoelemento, se puede hacer un truco para establecer el valor font-sizeen 0 para el elemento principal y restablecerlo a 14px para los elementos secundarios. El ejemplo de trabajo de este truco se puede ver aquí: http://jsfiddle.net/skip405/NfeVh/326/

skip405
fuente
1
Sin embargo, ¿hay alguna forma de evitar que el banner sea más alto? Me doy cuenta de cómo funciona esto, así que supongo que no.
mk12
1
Si está generando su contenido con javascript, tenga en cuenta que esta solución solo funciona si hay espacios en blanco entre los elementos. Deberá insertar un nodo de texto entre los elementos izquierdo / derecho o ambos se pegarán a la izquierda.
Stephen Nelson
1
¿Le importaría pegar su código aquí también? Los enlaces a lugares externos tienen la costumbre de morir en algún momento, y si eso sucede, esta respuesta que de otro modo sería útil se volverá inútil de repente.
OR Mapper
5
@ ValerioColtrè Estoy de acuerdo en que el espacio vacío es lo más (¡y posiblemente el único!) Molesto de este enfoque. Gestionar explícitamente su font-sizees bastante indeseable. Propongo una solución diferente. Tenga en cuenta que el .header:afterdecorador agrega una línea de altura igual a font-size. Afortunadamente sabemos cuánto es eso. ¡Es exactamente 1em! Entonces, ¡ márgenes negativos al rescate! Este violín muestra cómo .
Domi
1
@ skip405 Nota: establecer la altura de la línea en 0 en el elemento contenedor (encabezado) y arreglar la alineación vertical de su pseudoelemento (alineación vertical: superior, digamos) puede solucionar el problema de espacio adicional. Tenemos que, por supuesto, restablecer la altura de la línea en los elementos principales, pero puede ser más fácil en muchos casos. jsfiddle.net/bencergazda/3gL8153n/7
bencergazda
5

Aprovechando la respuesta de @ skip405, hice un mixin de 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 ajustar la pregunta, podría usarla así:

@include inline-block-lr('header', 'h1', 'nav');
Pablo SG Pacheco
fuente
3

Si no desea utilizar flotadores, tendrá que ajustar su navegador:

<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 agregue algunos CSS más específicos:

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;
}

Es posible que deba hacer un poco más, pero eso es un comienzo.

maiorano84
fuente
1

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

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

jdhartley
fuente
Supongo que todavía no estaba pensando en eso, simplemente parecía que sería más fácil de esta manera. Pero aparentemente no. ¿Alguna pista sobre cómo me conectaría a la navegación saltando a la siguiente línea desde javascript?
mk12
¡Ahh, puedo usar consultas de medios para esto! Pensé que solo se usaban al inicio, no al cambiar el tamaño. Gracias.
mk12
1

Creo que una posible solución a esto es usar 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/

robar
fuente
0

Visualización de los padres a la izquierda, en el centro y a la derecha. Si tiene más de 3 elementos, use nth-child () para ellos.

ingrese la descripción de la imagen aquí

Muestra HTML:

<body>
    <ul class="nav-tabs">
        <li><a  id="btn-tab-business" class="btn-tab nav-tab-selected"  onclick="openTab('business','btn-tab-business')"><i class="fas fa-th"></i>Business</a></li>
        <li><a  id="btn-tab-expertise" class="btn-tab" onclick="openTab('expertise', 'btn-tab-expertise')"><i class="fas fa-th"></i>Expertise</a></li>
        <li><a  id="btn-tab-quality" class="btn-tab" onclick="openTab('quality', 'btn-tab-quality')"><i class="fas fa-th"></i>Quality</a></li>
    </ul>
</body>

Muestra de CSS:

.nav-tabs{
  position: relative;
  padding-bottom: 50px;
}

.nav-tabs li {
  display: inline-block;  
  position: absolute;
  list-style: none;
}
.nav-tabs li:first-child{
  top: 0px;
  left: 0px;
}
.nav-tabs li:last-child{
  top: 0px;
  right: 0px;
}
.nav-tabs li:nth-child(2){
  top: 0px;
  left: 50%;
  transform: translate(-50%, 0%);
}
Señor
fuente
-1

dale float: right y h1 float: left y pon un elemento con clear: both después de ellos.

Itay Moav -Malimovka
fuente
8
" No quiero usar flotadores "
powerbuoy
@powerbuoy gracioso, seleccionó la solución con flotadores al final, ¿verdad?
Itay Moav -Malimovka
@Italia: Solo porque pensé que era la única forma posible, he cambiado mi respuesta aceptada.
mk12
-1

Para ambos elementos use

display: inline-block;

el para el uso del elemento 'nav'

float: right;
Sammy Aguns
fuente
2
Para un flotador no se puede usar envoltura.
Ievgen Naida