Выровняйте два встроенных блока слева и справа на одной строке


114

Как я могу выровнять два встроенных блока так, чтобы один был слева, а другой справа на одной строке? Почему это так сложно? Есть ли что-то вроде \ hfill LaTeX, которое может использовать пространство между ними для достижения этой цели?

Я не хочу использовать поплавки потому что с inline-block я могу выровнять базовые линии. И когда окно слишком мало для них обоих, с помощью встроенных блоков я могу просто изменить выравнивание текста по центру, и они будут центрированы один поверх другого. Относительное (родительское) + абсолютное (элемент) позиционирование имеет те же проблемы, что и поплавки.

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

Они рядом, но я хочу, чтобы они navбыли справа.

диаграмма


1
AFAIK единственный способ решить эту проблему - использовать поплавки или абсолютное позиционирование. Вы можете достичь того же базового положения, используя верхнюю границу поля навигации.
powerbuoy

Просто используйте margin-top и float. Это невозможно сделать без этого или абсолютного позиционирования.
jdhartley

Используйте медиа-запросы css, чтобы изменить CSS в зависимости от размера области просмотра. Вы можете использовать оба position: absoluteиinline-block
elclanrs

Ответы:


149

Изменить: прошло 3 года с тех пор, как я ответил на этот вопрос, и я думаю, что необходимо более современное решение, хотя текущее делает то же самое :)

1. Flexbox

Это, безусловно, самый короткий и гибкий. Примените display: flex;к родительскому контейнеру и отрегулируйте размещение его дочерних элементов justify-content: space-between;следующим образом:

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

Посмотреть онлайн можно здесь - http://jsfiddle.net/skip405/NfeVh/1073/

Однако обратите внимание, что поддержка flexbox - это 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, просто опустите свойства star-hack. Рабочий пример с использованием вашей разметки находится здесь - http://jsfiddle.net/skip405/NfeVh/5/ . Я просто добавил header:afterчасть и обосновал содержание.

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


1
Есть ли какой-нибудь способ помешать ему сделать баннер выше? Я понимаю, как это работает, поэтому предполагаю, что это не так.
mk12

1
Если вы создаете свой контент с помощью javascript, обратите внимание, что это решение работает, только если между элементами есть пробелы. Вам нужно будет вставить текстовый узел между левым и правым элементами, иначе они оба будут придерживаться левого края.
Стивен Нельсон

1
Не могли бы вы также вставить сюда свой код? Ссылки на внешние источники имеют свойство в какой-то момент умирать, и если это произойдет, этот полезный ответ внезапно станет бесполезным.
OR Mapper

5
@ ValerioColtrè Я согласен, что пустое пространство - это самая (и, возможно, единственная!) Раздражающая вещь в этом подходе. Явное управление своим font-sizeдовольно нежелательно. Предлагаю другое решение. Обратите внимание, что .header:afterдекоратор добавляет одну строку высотой, равной font-size. К счастью, мы знаем, сколько это стоит. Совершенно точно 1em! Итак, на помощь приходят отрицательные наценки ! Эта скрипка показывает, как это сделать .
Доми

1
@ skip405 Примечание: установка высоты строки на 0 в элементе оболочки (заголовок) и исправление вертикального выравнивания его псевдоэлемента (например, vertical-align: top) может решить проблему с лишним пространством. Мы, конечно, должны заново установить высоту строки для родительских элементов, но во многих случаях это может быть проще. jsfiddle.net/bencergazda/3gL8153n/7
bencergazda

5

Воспользовавшись ответом @skip405, я сделал для него миксин 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; 
    }
}

Он принимает 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

Отображение левого среднего и правого оттуда родителей. Если у вас более трех элементов, используйте для них 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: left и поместите элемент с clear: both после них.


8
« Я не хочу использовать поплавки »
powerbuoy

@powerbuoy забавно, он выбрал решение с поплавками в конце, верно?
Итай Моав -Малимовка

@Italy: Только потому, что я думал, что это единственно возможный способ - я изменил свой принятый ответ.
mk12

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.