Allinea due blocchi in linea a sinistra ea destra sulla stessa linea


113

Come posso allineare due blocchi in linea in modo che uno sia a sinistra e l'altro a destra sulla stessa linea? Perche'e'cosi difficile? C'è qualcosa come \ hfill di LaTeX che può consumare lo spazio tra di loro per ottenere questo risultato?

Non voglio usare i float perché con i blocchi inline posso allineare le linee di base. E quando la finestra è troppo piccola per entrambi, con i blocchi in linea posso semplicemente cambiare l'allineamento del testo al centro e saranno centrati uno sopra l'altro. Il posizionamento relativo (genitore) + assoluto (elemento) ha gli stessi problemi dei float.

L'HTML5:

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

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

Ce ne sono uno accanto all'altro, ma voglio quello nava destra.

un diagramma


1
AFAIK l'unico modo per risolvere questo problema è utilizzare i float o il posizionamento assoluto. È possibile ottenere la stessa posizione della linea di base utilizzando il margine superiore nel menu di navigazione.
powerbuoy

Usa solo margin-top e float. Non è possibile farlo senza quello o il posizionamento assoluto.
jdhartley

Utilizzare le query multimediali css per modificare il css a seconda delle dimensioni del viewport. Puoi usare sia position: absoluteeinline-block
elclanrs

Risposte:


147

Modifica: sono passati 3 anni da quando ho risposto a questa domanda e immagino che sia necessaria una soluzione più moderna, anche se quella attuale fa la cosa :)

1. Flexbox

È di gran lunga il più breve e flessibile. Applica display: flex;al contenitore padre e regola il posizionamento dei suoi figli in justify-content: space-between;questo modo:

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

Può essere visto online qui - http://jsfiddle.net/skip405/NfeVh/1073/

Si noti tuttavia che il supporto per flexbox è IE10 e versioni successive. Se è necessario supportare IE 9 o versioni precedenti, utilizzare la seguente soluzione:

2. Puoi usare la text-align: justifytecnica qui.

.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'esempio funzionante può essere visto qui: http://jsfiddle.net/skip405/NfeVh/4/ . Questo codice funziona da IE7 e versioni successive

Se gli elementi inline-block in HTML non sono separati da uno spazio, questa soluzione non funzionerà - vedi l'esempio http://jsfiddle.net/NfeVh/1408/ . Questo potrebbe essere il caso in cui inserisci contenuti con Javascript.

Se non ci interessa IE7, ometti semplicemente le proprietà star-hack. L'esempio funzionante che utilizza il tuo markup è qui: http://jsfiddle.net/skip405/NfeVh/5/ . Ho appena aggiunto la header:afterparte e giustificato il contenuto.

Per risolvere il problema dello spazio extra inserito con lo afterpseudoelemento si può fare un trucco per impostare font-sizea 0 per l'elemento genitore e resettarlo a dire 14px per gli elementi figlio. L'esempio funzionante di questo trucco può essere visto qui: http://jsfiddle.net/skip405/NfeVh/326/


1
C'è un modo per impedire che lo striscione più alto? Mi rendo conto di come funziona, quindi presumo che non sia così.
mk12

1
Se stai generando il tuo contenuto con javascript, tieni presente che questa soluzione funziona solo se c'è uno spazio bianco tra gli elementi. Dovrai inserire un nodo di testo tra gli elementi sinistro / destro o rimarranno entrambi a sinistra.
Stephen Nelson,

1
Ti dispiacerebbe incollare anche il tuo codice qui? I collegamenti a luoghi esterni hanno l'abitudine di morire ad un certo punto e, se ciò accade, questa risposta altrimenti utile diventerà improvvisamente inutile.
OR Mapper

5
@ ValerioColtrè Concordo sul fatto che lo spazio vuoto sia la cosa più (e forse l'unica!) Fastidiosa di questo approccio. Gestire esplicitamente il tuo font-sizeè piuttosto indesiderabile. Propongo una soluzione diversa. Notare che il .header:afterdecoratore aggiunge una linea di altezza uguale a font-size. Fortunatamente sappiamo quanto sia. È esattamente 1em! Quindi, margini negativi in soccorso! Questo violino mostra come .
Domi

1
@ skip405 Nota: impostare l'altezza della riga su 0 sull'elemento wrapper (intestazione) e correggere l'allineamento verticale del suo pseudo elemento (vertical-align: top, diciamo) può risolvere il problema dello spazio aggiuntivo. Dobbiamo, ovviamente, reimpostare l'altezza della linea sugli elementi principali, ma in molti casi può essere più semplice. jsfiddle.net/bencergazda/3gL8153n/7
bencergazda

5

Approfittando della risposta di @ skip405, ho creato un mixin Sass per questo:

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

Accetta 3 parametri. Il contenitore, l'elemento sinistro e quello destro. Ad esempio, per soddisfare la domanda, potresti usarlo in questo modo:

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

3

Se non vuoi usare i float, dovrai avvolgere il tuo 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>

... e aggiungi un css più specifico:

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

Potrebbe essere necessario fare un po 'di più, ma questo è un inizio.


1

Se stai già utilizzando JavaScript per centrare le cose quando lo schermo è troppo piccolo (come per il tuo commento per la tua intestazione), perché non annullare semplicemente i float / margini con JavaScript mentre ci sei e usa i float ei margini normalmente.

Puoi anche utilizzare le query multimediali CSS per ridurre la quantità di JavaScript che stai utilizzando.


Immagino che non ci stavo ancora pensando, sembrava che sarebbe stato più facile in questo modo. Ma a quanto pare no. Qualche suggerimento su come mi collegherei al nav saltando alla riga successiva da javascript?
mk12

Ahh, posso usare le media query per questo! Pensavo fossero usati solo all'avvio, non al ridimensionamento. Grazie.
mk12

1

Penso che una possibile soluzione a questo sia usare 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

Visualizzazione di sinistra centrale e destra di lì genitori. Se hai più di 3 elementi, usa nth-child () per loro.

inserisci qui la descrizione dell'immagine

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

Esempio 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%);
}

-1

dategli float: right e h1 float: left e mettete un elemento con clear: entrambi dopo di loro.


8
" Non voglio usare galleggianti "
powerbuoy

@ powerbuoy divertente ha selezionato la soluzione con i galleggianti alla fine, giusto?
Itay Moav -Malimovka

@Italy: Solo perché pensavo che fosse l'unico modo possibile - ho cambiato la mia risposta accettata.
mk12

-1

Per entrambi gli elementi utilizzare

display: inline-block;

il per l'uso dell'elemento "nav"

float: right;

2
Per un galleggiante non è possibile utilizzare alcun avvolgimento.
Ievgen Naida
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.