Вирівняйте два вбудовані блоки ліворуч та праворуч на одній лінії


113

Як я можу вирівняти два вбудовані блоки, щоб один був лівим, а другий - правим на тій же лінії? Чому це так важко? Чи є щось на зразок LaTeX \ hfill, яке може зайняти простір між ними для досягнення цього?

Я не хочу використовувати поплавці, тому що за допомогою вбудованих блоків я можу вирівняти базові лінії. І коли вікно занадто мало для обох, за допомогою вбудованих блоків я можу просто змінити вирівнювання тексту на центр, і вони будуть розташовані по центру один на інший. Відносне (батьківське) + абсолютне (елементне) позиціонування має ті самі проблеми, що і плаваючі.

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

Thery прямо поруч, але я хочу, navщоб справа.

діаграма


1
AFAIK єдиний спосіб вирішити це - використовувати поплавці або абсолютне позиціонування. Ви можете досягти тієї ж базової позиції, використовуючи margin-top на nav.
powerbuoy

Просто використовуйте margin-top і floats. Це неможливо зробити без цього або абсолютного позиціонування.
jdhartley

Використовуйте мультимедійні запити css, щоб змінити css залежно від розміру вікна перегляду. Ви можете використовувати як position: absoluteіinline-block
elclanrs

Відповіді:


147

Редагувати: минуло 3 роки, з тих пір, як я відповів на це запитання, і, мабуть, потрібно більш сучасне рішення, хоча нинішнє це робить :)

1. Flexbox

Це, безумовно, найкоротший і гнучкий. Зверніться display: flex;до батьківського контейнера і відрегулюйте розміщення його дітей justify-content: space-between;таким чином:

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

Тут можна побачити онлайн - http://jsfiddle.net/skip405/NfeVh/1073/

Зауважте, що підтримка флешбоксу є IE10 та новішою. Якщо вам потрібно підтримувати IE 9 або новішу версію, скористайтеся наступним рішенням:

2.Ви можете використовувати text-align: justifyтут техніку.

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

Робочий приклад можна побачити тут: http://jsfiddle.net/skip405/NfeVh/4/ . Цей код працює від IE7 і вище

Якщо елементи вбудованого блоку в HTML не розділені з пробілом, це рішення не працюватиме - див. Приклад http://jsfiddle.net/NfeVh/1408/ . Це може бути випадок, коли ви вставляєте вміст за допомогою JavaScript.

Якщо нам не байдуже IE7, просто опустіть властивості зірки. Робочий приклад з використанням розмітки тут - http://jsfiddle.net/skip405/NfeVh/5/ . Я щойно додавheader:after частину і виправдав зміст.

Щоб вирішити питання про додатковий простір, який вставляється з afterпсевдоелементом, можна зробити фокус встановлення значення font-size0 для батьківського елемента та скидання його назад, щоб сказати 14 пікселів для дочірніх елементів. Робочий приклад цього фокусу можна побачити тут: http://jsfiddle.net/skip405/NfeVh/326/


1
Чи є якийсь спосіб запобігти зростанню банера вище? Я розумію, як це працює, тому я б припустив, що цього немає.
mk12

1
Якщо ви генеруєте свій вміст за допомогою JavaScript, зауважте, що це рішення працює лише за наявності проміжків між елементами. Вам потрібно буде вставити текстовий вузол між лівими / правими елементами, інакше вони будуть дотримуватися ліворуч.
Стівен Нельсон

1
Ви також не хочете вставити свій код сюди? Посилання на зовнішні місця мають звичку вмирати в якийсь момент, і якщо це станеться, ця інакше корисна відповідь раптом стане марною.
АБО Mapper

5
@ ValerioColtrè Я погоджуюся, що порожній простір є найбільш (і, можливо, єдиним!) Дратівливим у цьому підході. Безпосередньо керувати своїм font-sizeдосить небажано. Я пропоную інше рішення. Зауважте, що .header:afterдекоратор додає одну лінію висоти, рівну font-size. На щастя, ми знаємо, наскільки це. Це саме 1em! Отже, негативна націнка на допомогу! Ця скрипка показує, як .
Домі

1
@ skip405 Примітка: встановлення висоти лінії на 0 на обгортковому елементі (заголовку) та виправлення вертикального вирівнювання його псевдоелемента (вертикальне вирівнювання: верх, скажімо) може вирішити додаткову проблему з простором. Треба, звичайно, знову встановити висоту лінії на батьківських елементах, але це може бути простіше у багатьох випадках. jsfiddle.net/bencergazda/3gL8153n/7
bencergazda

5

Скориставшись відповіддю @ skip405, я зробив для цього Sass mixin:

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

Він приймає 3 параметри. Контейнер, лівий і правий елемент. Наприклад, щоб відповісти на запитання, ви можете використовувати його так:

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

3

Якщо ви не хочете використовувати поплавці, вам доведеться завернути свій навичок:

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

... і додайте ще більш конкретний 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;
}

Можливо, вам доведеться зробити трохи більше, але це початок.


1

Якщо ви вже використовуєте JavaScript для централізації матеріалів, коли екран занадто малий (відповідно до вашого коментаря до вашого заголовка), чому б просто не скасувати плавання / поля з JavaScript, поки ви знаходитесь у ньому, і використовувати плавки та поля зазвичай.

Ви навіть можете використовувати медіа-запити CSS, щоб зменшити кількість JavaScript, який ви використовуєте.


Я думаю, я ще не дуже думав про це, просто здавалося, що так буде легше. Але, мабуть, ні. Будь-які підказки щодо того, як я підключусь до навігаційного переходу до наступного рядка з JavaScript?
mk12

Ах, я можу використовувати для цього медіа-запити! Я думав, що вони використовуються лише під час запуску, а не на розмірі. Дякую.
mk12

1

Я думаю, що одним із можливих рішень для цього є використання 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

Відображення лівих посередині та праворуч батьків. Якщо у вас більше 3 елементів, тоді використовуйте для них nth-child ().

введіть тут опис зображення

Зразок 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>

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

дайте йому float: right та h1 float: ліворуч та поставте елемент з clear: обидва після них.


8
" Я не хочу використовувати поплавці "
powerbuoy

@powerbuoy смішно він вибрав рішення з поплавцями в кінці, правда?
Itay Moav -Malimovka

@Italy: Тільки тому, що я думав, що це єдино можливий шлях - я змінив свою прийняту відповідь.
mk12

-1

Для обох елементів використання

display: inline-block;

для використання елемента 'nav'

float: right;

2
Для поплавця жодне обгортання використовувати не можна.
Євген Найда
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.