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

113

Comment puis-je aligner deux blocs en ligne de sorte que l'un soit à gauche 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 flotteurs car avec des blocs en ligne, je peux aligner les lignes de base. Et lorsque la fenêtre est trop petite pour les deux, avec des blocs en ligne, je peux simplement changer l'alignement du texte 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 juste l'un à côté de l'autre, mais je veux qu'ils soient à navdroite.

un diagramme

mk12
la source
1
AFAIK le seul moyen de résoudre ce problème est d'utiliser des flotteurs ou un positionnement absolu. Vous pouvez obtenir la même position de ligne de base en utilisant margin-top sur la navigation.
powerbuoy
Utilisez simplement le haut de la marge et les flotteurs. Il n'est pas possible de faire cela sans cela ou sans positionnement absolu.
jdhartley
Utilisez les requêtes multimédias css pour modifier le css en fonction de la taille de la fenêtre. Vous pouvez utiliser à la fois position: absoluteetinline-block
elclanrs

Réponses:

147

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

1. Flexbox

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

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

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

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

2.Vous pouvez utiliser la text-align: justifytechnique 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 d'IE7 et au-dessus

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

Si nous ne nous soucions pas d'IE7, omettez simplement les propriétés star-hack. L'exemple de travail utilisant votre balisage est ici - http://jsfiddle.net/skip405/NfeVh/5/ . J'ai juste ajouté la header:afterpartie et justifié le contenu.

Afin de résoudre le problème de l'espace supplémentaire inséré avec le afterpseudo-élément, on peut faire une astuce en définissant le font-sizeà 0 pour l'élément parent et en le réinitialisant à 14px pour les éléments enfants. L'exemple de travail de cette astuce peut être vu ici: http://jsfiddle.net/skip405/NfeVh/326/

sauter405
la source
1
Y a-t-il un moyen de l'empêcher d'élargir la bannière? Je réalise comment cela fonctionne, alors je suppose que non.
mk12
1
Si vous générez votre contenu avec javascript, notez que cette solution ne fonctionne que s'il y a des espaces entre les éléments. Vous devrez insérer un nœud de texte entre les éléments gauche / droit ou ils resteront tous les deux à gauche.
Stephen Nelson
1
Pourriez-vous également coller votre code ici? Les liens vers des lieux extérieurs ont l'habitude de mourir à un moment donné, et si cela se produit, cette réponse autrement utile deviendra soudainement inutile.
OR Mapper
5
@ ValerioColtrè Je suis d'accord que l'espace vide est la chose la plus (et peut-être la seule!) Ennuyeuse de cette approche. La gestion explicite de votre font-sizeest plutôt indésirable. Je propose une solution différente. Notez que le .header:afterdécorateur ajoute une ligne de hauteur égale à font-size. Heureusement, nous savons combien cela représente. C'est exactement ça 1em! Alors, des marges négatives à la rescousse! Ce violon montre comment .
Domi
1
@ skip405 Remarque: régler la hauteur de ligne à 0 sur l'élément wrapper (en-tête) et fixer l'alignement vertical de son pseudo élément (vertical-align: top, par exemple) peut résoudre le problème d'espace supplémentaire. Nous devons bien sûr redéfinir la hauteur de ligne sur les éléments parents, mais cela peut être plus facile dans de nombreux cas. jsfiddle.net/bencergazda/3gL8153n/7
bencergazda
5

Profitant de la réponse de @ skip405, j'ai fait 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 répondre à la question, vous pouvez l'utiliser comme ceci:

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

Si vous ne souhaitez pas utiliser de flotteurs, vous devrez envelopper votre 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>

... et ajoutez 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.

maiorano84
la source
1

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 simplement annuler les flottants / marges avec JavaScript pendant que vous y êtes et utiliser les flottants et les marges normalement.

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

jdhartley
la source
Je suppose que je n'y pensais pas encore vraiment, il semblait juste que ce serait plus facile de cette façon. Mais apparemment non. Des conseils sur la façon dont je me connecterais à la navigation en passant à la ligne suivante à partir de javascript?
mk12
Ahh, je peux utiliser les requêtes média pour ça! Je pensais que ceux-ci n'étaient utilisés qu'au démarrage, pas lors du redimensionnement. Merci.
mk12
1

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/

volé
la source
0

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

Grille :

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

Démo

Bootstrap 4. Alignez à 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

Ievgen Naida
la source
0

Affichage au milieu à gauche et à droite de leurs parents. Si vous avez plus de 3 éléments, utilisez nth-child () pour eux.

entrez la description de l'image ici

Exemple 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>

Exemple 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%);
}
Seigneur
la source
-1

donnez-lui float: right et le h1 float: left et mettez un élément avec clear: both après eux.

Itay Moav -Malimovka
la source
8
" Je ne veux pas utiliser de flotteurs "
powerbuoy
@powerbuoy drôle, il a choisi la solution avec des flotteurs à la fin, non?
Itay Moav - Malimovka
@Italie: Seulement parce que je pensais que c'était le seul moyen possible - j'ai changé ma réponse acceptée.
mk12
-1

Pour les deux éléments, utilisez

display: inline-block;

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

float: right;
Sammy Aguns
la source
2
Pour un flotteur, aucune enveloppe ne peut être utilisée.
Ievgen Naida