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

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

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

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're находятся рядом друг с другом, но я хочу nav справа.

a diagram

Ответ 1

Изменить: Прошло 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-size на 0 для родительского элемента и сбросить его обратно, чтобы сказать 14px для дочерние элементы. Рабочий пример этого трюка можно увидеть здесь: http://jsfiddle.net/skip405/NfeVh/326/

Ответ 2

Если вы не хотите использовать float, вам придется обернуть ваш 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>

... и добавьте еще несколько конкретных 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;
}

Вам может потребоваться немного больше, но это начало.

Ответ 3

Воспользовавшись ответом @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');

Ответ 4

Если вы уже используете JavaScript для центра, когда экран слишком мал (согласно вашему комментарию для вашего заголовка), почему бы не просто отменить поплавки/поля с помощью JavaScript, пока вы на нем, и обычно используете поплавки и поля.

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

Ответ 5

дайте ему float: right и h1 float: left и поместите элемент с ясными: как после них.

Ответ 6

Я думаю, что одним из возможных решений для этого является использование 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/

Ответ 7

Для обоих элементов div используйте

display: inline-block;

для второго элемента div используйте

float: right;