Wyrównaj dwa wbudowane bloki po lewej i prawej stronie w tej samej linii


113

Jak mogę wyrównać dwa bloki inline, tak aby jeden był po lewej, a drugi po prawej w tej samej linii? Dlaczego to takie trudne? Czy jest coś takiego jak \ hfill LaTeX-a, które może zająć przestrzeń między nimi, aby to osiągnąć?

Nie chcę używać pływaków, ponieważ dzięki blokom inline mogę wyrównać linie bazowe. A kiedy okno jest za małe dla nich obu, za pomocą bloków inline mogę po prostu zmienić wyrównanie tekstu na środek, a zostaną wyśrodkowane jeden na drugim. Pozycjonowanie względne (nadrzędne) + bezwzględne (element) ma te same problemy, co elementy zmiennoprzecinkowe.

HTML5:

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

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

Są tuż obok siebie, ale ja chcę navpo prawej stronie.

diagram


1
AFAIK jedynym sposobem rozwiązania tego problemu jest użycie wartości zmiennoprzecinkowych lub pozycjonowania bezwzględnego. Możesz osiągnąć tę samą pozycję bazową, używając górnej krawędzi marginesu na panelu nawigacyjnym.
— powerbuoy

Po prostu użyj marginesów i pływaków. Nie można tego zrobić bez tego lub pozycjonowania absolutnego.
— jdhartley

Użyj zapytań o media css, aby zmienić css w zależności od rozmiaru widocznego obszaru. Możesz użyć obu position: absoluteiinline-block
— elclanrs

Odpowiedzi:


147

Edycja: minęły 3 lata odkąd odpowiedziałem na to pytanie i myślę, że potrzebne jest bardziej nowoczesne rozwiązanie, chociaż obecne robi to :)

1. Flexbox

To zdecydowanie najkrótszy i najbardziej elastyczny. Zastosuj display: flex;do kontenera nadrzędnego i dostosuj położenie jego elementów podrzędnych w justify-content: space-between;następujący sposób:

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

Można go zobaczyć online tutaj - http://jsfiddle.net/skip405/NfeVh/1073/

Należy jednak pamiętać, że obsługa flexbox to IE10 i nowsze. Jeśli potrzebujesz obsługi przeglądarki IE 9 lub starszej, użyj następującego rozwiązania:

2. Możesz użyć tej text-align: justifytechniki tutaj.

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

Działający przykład można zobaczyć tutaj: http://jsfiddle.net/skip405/NfeVh/4/ . Ten kod działa od IE7 i nowszych

Jeśli elementy inline-block w HTML nie są oddzielone spacjami, to rozwiązanie nie zadziała - zobacz przykład http://jsfiddle.net/NfeVh/1408/ . Może tak być w przypadku wstawiania treści za pomocą JavaScript.

Jeśli nie obchodzi nas IE7, po prostu pomiń właściwości star-hack. Działający przykład wykorzystujący twoje znaczniki jest tutaj - http://jsfiddle.net/skip405/NfeVh/5/ . Właśnie dodałem header:afterczęść i uzasadniłem treść.

W celu rozwiązania problemu dodatkowej przestrzeni wstawianej z afterpseudoelementem można wykonać sztuczkę polegającą na ustawieniu wartości font-size0 dla elementu nadrzędnego i zresetowaniu go z powrotem do 14 pikseli dla elementów potomnych. Działający przykład tej sztuczki można zobaczyć tutaj: http://jsfiddle.net/skip405/NfeVh/326/


1
Czy jest jakiś sposób, aby powstrzymać go przed podwyższeniem banera? Zdaję sobie sprawę, jak to działa, więc zakładam, że tak nie jest.
— mk12

1
Jeśli generujesz zawartość za pomocą javascript, pamiętaj, że to rozwiązanie działa tylko wtedy, gdy między elementami są spacje. Będziesz musiał wstawić węzeł tekstowy między lewy / prawy element lub oba będą trzymane po lewej stronie.
— Stephen Nelson

1
Czy mógłbyś również wkleić tutaj swój kod? Linki do zewnętrznych miejsc mają w zwyczaju umierać w pewnym momencie, a jeśli tak się stanie, ta użyteczna odpowiedź nagle stanie się bezużyteczna.
— LUB Mapper

5
@ ValerioColtrè Zgadzam się, że pusta przestrzeń jest najbardziej (i prawdopodobnie jedyną!) Irytującą rzeczą w tym podejściu. Jawne zarządzanie swoim font-sizejest raczej niepożądane. Proponuję inne rozwiązanie. Zauważ, że .header:afterdekorator dodaje jedną linię o wysokości równej font-size. Na szczęście wiemy, ile to kosztuje. To jest dokładnie 1em! A więc ujemne marże na ratunek! To skrzypce pokazuje, jak to zrobić .
— Domi

1
@ skip405 Uwaga: ustawienie wysokości linii na 0 w elemencie opakowującym (nagłówku) i naprawienie wyrównania w pionie jego pseudoelem (powiedzmy vertical-align: top) może rozwiązać problem dodatkowej przestrzeni. Oczywiście musimy ponownie ustawić wysokość linii w elementach nadrzędnych, ale w wielu przypadkach może to być łatwiejsze. jsfiddle.net/bencergazda/3gL8153n/7
— bencergazda

5

Korzystając z odpowiedzi @ skip405, stworzyłem dla niej mixin Sass:

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

Przyjmuje 3 parametry. Kontener, lewy i prawy element. Na przykład, aby dopasować pytanie, możesz użyć tego w następujący sposób:

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

3

Jeśli nie chcesz używać pływaków, będziesz musiał zawinąć swoją nawigację:

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

... i dodaj bardziej szczegółowe css:

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

Być może będziesz musiał zrobić trochę więcej, ale to początek.


1

Jeśli już używasz JavaScript do wyśrodkowania rzeczy, gdy ekran jest zbyt mały (zgodnie z komentarzem do twojego nagłówka), dlaczego nie cofnąć ruchów / marginesów za pomocą JavaScript, gdy jesteś przy tym i normalnie używaj pływaków i marginesów.

Możesz nawet użyć zapytań o media CSS, aby zmniejszyć ilość używanego kodu JavaScript.


Chyba jeszcze o tym nie myślałem, po prostu wydawało mi się, że w ten sposób będzie łatwiej. Ale najwyraźniej nie. Jakieś wskazówki, jak podłączyć się do nawigacji przechodząc do następnej linii z javascript?
— mk12

Ach, mogę w tym celu użyć zapytań o media! Myślałem, że te były używane tylko podczas uruchamiania, a nie podczas zmiany rozmiaru. Dzięki.
— mk12

1

Myślę, że jednym z możliwych rozwiązań jest użycie 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

Wyświetlanie lewej środkowej i prawej strony rodziców. Jeśli masz więcej niż 3 elementy, użyj dla nich nth-child ().

wprowadź opis obrazu tutaj

Przykład 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>

Przykład 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

daj mu float: right i h1 float: left i wstaw element z clear: oba po nich.


8
„ Nie chcę używać pływaków ”
— powerbuoy

@powerbuoy zabawne, że wybrał rozwiązanie z pływakami na końcu, prawda?
— Itay Moav -Malimovka

@Włochy: Tylko dlatego, że myślałem, że to jedyny możliwy sposób - zmieniłem zaakceptowaną odpowiedź.
— mk12

-1

Do obu elementów użyj

display: inline-block;

do użycia elementu „nav”

float: right;

2
W przypadku pływaka nie można stosować zawijania.
— Ievgen Naida
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.