"text-align: justify;" встроенные элементы блока?

Несколько других вопросов уже рассмотрели, как наилучшим образом применить text-align: justify, чтобы получить элементы линейного блока для равномерного распределения... например, Как я * действительно * оправдываю горизонтальное меню в HTML + CSS?

Однако элемент 100% ширины, который "очищает" строку элементов встроенного блока, получает свою собственную строку браузером. Я не могу понять, как избавиться от этого пустого вертикального пространства, не используя line-height: 0; в родительском элементе.

Пример проблемы см. в этой скрипке

Для моего решения, использующего line-height: 0;, см. эту скрипту

Решение, которое я использую, требует, чтобы к дочерним элементам был применен новый line-height, но любой ранее установленный line-height был потерян. Кто-нибудь знает о лучшем решении? Я хочу избегать таблиц, чтобы элементы могли обертываться при необходимости, а также flexbox, потому что поддержки браузера еще нет. Я также хочу избежать float, потому что количество разнесенных элементов будет произвольным.

Ответ 1

Обновлена ​​информация о "Будущем" ниже; еще не полностью поддерживается.

Нынешнее временное решение (IE8 +, FF, Chrome Tested)

Посмотрите эту скрипту.

Соответствующий CSS

.prevNext {
    text-align: justify;
}

.prevNext a {
    display: inline-block;
    position: relative;
    top: 1.2em; /* your line-height */
}

.prevNext:before{
    content: '';
    display: block;
    width: 100%;
    margin-bottom: -1.2em; /* your line-height */
}

.prevNext:after {
    content: '';
    display: inline-block;
    width: 100%;
}

Объяснение

Элемент display: block в элементе :before с отрицательным нижним полем тянет строки текста вверх на одну высоту строки, что исключает дополнительную строку, но смещает текст. Затем с position: relative на элементах inline-block смещение переносится, но без добавления дополнительной строки назад.

Хотя css не может напрямую получить доступ к элементу line-height как таковому, использование em в настройках margin-bottom и top легко вмещает любой line-height, указанный как один из значения множителя. Таким образом, 1.2, 120% или 1.2em все равны в расчете по line-height, что делает использование em хорошим выбором здесь, так как даже если line-height: 1.2 установлено, то 1.2em > для margin-bottom и top. Хорошее кодирование для нормализации внешнего вида сайта означает, что в какой-то момент line-height должно быть определено явно, поэтому, если используется какой-либо из методов множителя, то эквивалентный блок em будет давать то же значение, что и line-height. И если для параметра line-height задана длина не em, например px, это может быть установлено.

Определенно наличие переменной или mixin с использованием препроцессора css, такого как LESS или SCSS, может помочь сохранить эти значения, соответствующие соответствующему line-height, или javascript можно использовать для динамического чтения таких, но на самом деле следует знать line-height в контексте того, где это используется, и соответствующие настройки здесь.

ОБНОВЛЕНИЕ для проблемы с сокращенным текстом (без пробелов)

Комментарий Kubi отметил, что минимизация html, которая удаляет пробелы между элементами <a> приводит к отказу оправдания. A псевдопространство в теге <a> не помогает (но это ожидается, поскольку пространство происходит внутри элемента inline-block), a <wbr>, добавленный между тегами <a>, не помогает (вероятно, потому, что разрыв не нужен для следующей строки), поэтому, если требуется минимизация, тогда решение является жестко закодированным неразрывным символом пробела &nbsp; - другие пробелы, такие как тонкое пространство и en space не работает (на удивление).

Ближайшее будущее решение

Решение, в котором webkit было за раз (начиная с первого раза)

.prevNext {
    text-align: justify;
    -moz-text-align-last: justify;
    -webkit-text-align-last: justify; /* not implemented yet, and will not be */
    text-align-last: justify; /* IE */
}

Он работает в FF 12.0+ и IE8 + (багги в IE7).

Для Webkit, начиная с версии 39 (по крайней мере, возможно, он закрался ранее), он поддерживает без расширения -webkit-, но , только если пользователь включил экспериментальные функции (что можно сделать при chrome://flags/#enable-experimental-web-platform-features). Ходят слухи, что версия 41 или 42 должна увидеть полную поддержку. Так как он webkit не поддерживается, , это еще только частичное решение. Однако я думал, что должен опубликовать его, поскольку он может быть полезен для некоторых.

Ответ 2

Рассмотрим следующее:

.prevNext {
    display: table;
    width: 100%
}

.prevNext a {
    display: table-cell;
    text-align: center
}

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

Ответ 3

Во-первых, мне нравится подход pseudo-element, чтобы сохранить семантику разметки. Я думаю, вы должны придерживаться общего подхода. Это намного лучше, чем прибегать к таблицам, ненужной разметке или поверх верхних скриптов, чтобы захватить данные позиционирования.

Для всех было подчеркнуто, что text-align является взломанным - c'mon! Лучше, чтобы html был семантическим за счет CSS, чем наоборот.

Итак, по моему мнению, вы пытаетесь добиться этого обоснованного эффекта встроенного блока, не беспокоясь о том, чтобы каждый раз перезагружать line-height? Я утверждаю, что вы просто добавляете

.prevNext *{
    line-height: 1.2;  /* or normal */
}

Тогда вы можете идти о кодировании, как будто ничего не произошло. Здесь Павел Ирландский цитирует о селекторе *, если вы беспокоитесь о производительности:

"... вам не разрешается заботиться о производительности *, если вы не соедините все свои javascript, не поставите его внизу, не минимизируйте свои css и js, gzip все свои активы и без сжатия скомпрессируйте все ваши изображения. вы не получаете более 90 баллов по скорости страницы, это слишком рано, чтобы думать о оптимизации выбора".

Надеюсь, это поможет!

-J Коул Моррисон

Ответ 4

Попытка text-align для этой проблемы довольно хакерская. Свойство text-align предназначено для выравнивания встроенного содержимого блока (в частности, текста) - он не предназначен для выравнивания элементов html.

Я понимаю, что вы пытаетесь избежать float, но, на мой взгляд, floats - лучший способ выполнить то, что вы пытаетесь сделать.

Ответ 5

В вашем примере у вас есть line-height:1.2, без единицы. Это может вызвать проблемы. Если вы не используете границы, вы можете дать родителям и детям a line-height of 0.

Другие варианты, о которых я могу думать, следующие:

  • Используйте display:table для родителя и display:table-cell для детей, чтобы имитировать поведение таблицы как. И вы выравниваете первый элемент влево, а последний - вправо. Смотрите скрипка.
  • Используйте javascript для подсчета числа дочерних элементов nav, а затем дайте им одинаково распределенную ширину. например. 4 детей, 25% width каждый. И выровняйте первый и последний элементы слева и справа соответственно.
  • Существует способ равномерного распределения элементов, но это сложный метод, который требует, чтобы некоторые неперекрывающиеся пространства были тщательно помещены в html вместе с отрицательным полем и text-align:justify. Вы можете попробовать и приспособить его к элементу nav. Пример здесь.

Ответ 6

Ваша скрипка ужасно специфична. Мне кажется, что ваш CSS-код будет работать хорошо:

.prevNext {
    border: 1px solid #ccc;
    position: relative;
    height: 1.5em;
}

.prevNext a {
    display: block;
    position: absolute;
    top: 0;
}

.prevNext a:first-child {
    left: 0;
    text-align: left;
}
.prevNext a:last-child {
    right: 0;
    text-align: right;
}
​

Ответ 7

Как указано в @Scotts, внутри Chrome реализовано следующее: без части -webkit, которую я действительно любил btw, особенно потому, что нам нужно скоро избавиться от -browser-specific-shǐt.

.prevNext {
    text-align: justify;
    -moz-text-align-last: justify;
    -webkit-text-align-last: justify; /* not implemented yet, and will not be */
    text-align-last: justify; /* IE + Chrome */
}

Примечание: Хотя все еще Safari и Opera еще не поддерживают его (08-SEPT-16).

Ответ 8

Я думаю, что лучший способ - создать интерактивный элемент с определенным class/id, а затем назначить float:left или float:right соответственно. Надеюсь, это поможет.