web-dev-qa-db-fra.com

Aligner deux blocs en ligne à gauche et à droite sur la même ligne

Comment puis-je aligner deux blocs en ligne afin que l'un soit laissé et l'autre à droite sur la même ligne? Pourquoi est-ce si difficile? Y a-t-il quelque chose comme\hfill de LaTeX qui peut consommer l'espace entre eux pour y parvenir?

Je ne veux pas utiliser de float car avec des blocs en ligne, je peux aligner les lignes de base. Et lorsque la fenêtre est trop petite pour eux deux, avec des blocs en ligne, je peux simplement changer le texte-aligner au centre et ils seront centrés l'un sur l'autre. Le positionnement relatif (parent) + absolu (élément) pose les mêmes problèmes que les flottants.

Le HTML5:

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

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

Ils sont l'un à côté de l'autre, mais je veux que la nav soit à droite.

a diagram

91
mk12

Edit: 3 ans se sont écoulés depuis que j'ai répondu à cette question et j'imagine qu'une solution plus moderne est nécessaire, bien que l'actuelle soit la solution :)

1. Flexbox

C'est de loin le plus court et le plus flexible. Appliquez display: flex; au conteneur parent et ajustez le placement de ses enfants par justify-content: space-between; comme suit:

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

Peut être vu en ligne ici - http://jsfiddle.net/skip405/NfeVh/1073/

Notez cependant que flexbox support est IE10 et plus récent. Si vous devez prendre en charge IE 9 ou une version plus ancienne, utilisez la solution suivante:

2.Vous pouvez utiliser la technique text-align: justify ici.

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

L'exemple de travail peut être vu ici: http://jsfiddle.net/skip405/NfeVh/4/ . Ce code fonctionne à partir de IE7 et supérieur

Si les éléments inline-block en HTML ne sont pas séparés par un espace, cette solution ne fonctionnera pas - voir exemple http://jsfiddle.net/NfeVh/1408/ . Cela peut être le cas lorsque vous insérez du contenu avec Javascript.

Si nous ne nous intéressons pas à IE7, omettez simplement les propriétés star-hack. L'exemple de travail utilisant votre balise est ici - http://jsfiddle.net/skip405/NfeVh/5/ . Je viens d'ajouter la partie header:after et de justifier le contenu.

Afin de résoudre le problème de l'espace supplémentaire inséré avec le pseudo-élément after, il est possible de régler le code font-size à 0 pour l'élément parent et de le réinitialiser à 14 pixels pour les éléments enfants. L'exemple de travail de cette astuce peut être vu ici: http://jsfiddle.net/skip405/NfeVh/326/

119
skip405

Profitant de la réponse de @ skip405, j'ai créé un mixin Sass pour cela:

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

Il accepte 3 paramètres. Le conteneur, les éléments gauche et droit. Par exemple, pour adapter la question, vous pouvez l’utiliser comme suit:

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

Si vous ne voulez pas utiliser de float, vous devrez envelopper votre navigation:

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

... et ajouter des css plus spécifiques:

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

Vous devrez peut-être faire un peu plus, mais c'est un début.

3
maiorano84

Si vous utilisez déjà JavaScript pour centrer des éléments lorsque l'écran est trop petit (selon votre commentaire pour votre en-tête), pourquoi ne pas annuler les flottants/marges avec JavaScript lorsque vous y êtes et utilisez les flottants et les marges normalement.

Vous pouvez même utiliser des requêtes de média CSS pour réduire la quantité de JavaScript que vous utilisez.

1
jdhartley

Je pense qu'une solution possible à cela est d'utiliser 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
robd

Nouvelles façons d'aligner les éléments correctement:

La grille :

.header {
        display:grid;
        grid-template-columns: 1fr auto;
    }

Démo

Bootstrap 4. Aligner à droite :

<div class="row">
      <div class="col">left</div>
      <div class="col">
          <div class="float-right">element needs to be right aligned</div>
      </div>
</div>

Démo

0
Ievgen Naida

Pour les deux éléments, utilisez

display: inline-block;

l'utilisation de l'élément 'nav'

float: right;
0
Sammy Aguns