Как я могу равномерно сбалансировать текст по нескольким строкам?

Я хотел бы отобразить короткий фрагмент текста, который может переноситься на две или три строки. Он находится внутри визуального элемента, и для стилизации я бы хотел, чтобы линии были как можно более одинаковыми по длине, предпочитая одну линию двум.

Вместо этого:

Это пример фрагмента текста, который будет переноситься на два

линий.

Я хочу этот:

Это пример куска

текст, который будет переноситься в две строки.

Но я не хочу ограничивать ширину текстового контейнера:

Этот текст достаточно длинный, чтобы едва уместиться в две строки. Это

не следует переносить на три или более строк, чтобы не было ограничений по ширине.

Есть ли способ сделать это в чистом CSS или с приемлемым количеством JavaScript?

8 ответов

Решение

2016 ответ: CSS4:

 text-wrap: balance;

Сделаю это. https://drafts.csswg.org/css-text-4/

Также есть пакет, который реализует полифил для существующих браузеров.

Вот демонстрация баланса текста.

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

Единственный способ увидеть то, что вы просите, - это сравнить ширину текста с шириной контейнера и соответствующим образом изменить его.

Формула: ширина отдельной строки = ширина текста / roundUp (ширина текста / ширина контейнера)

то есть (вероятно, нужна некоторая корректировка, чтобы не разрезать слова пополам)

var widthOfText = functionToGetWidthOfText(width); //==120
var widthOfContainer = container.width(); //==100
var containerWidth = widthOfText / ceil(widthOfText/widthOfContainer);
// containerWidth = 120 / ceil(120/100) == 120 / 2 == 60
var formattingTextContainer.width = containerWidth
// text would go inside the formattingTextContainer, which would
// give you 2 lines of equal, 60px width

Однако проблема с этим заключается в создании "functionToGetWidthOfText". После некоторого быстрого поиска, все, что я нашел, это вопрос переполнения стека, где ответ на...

Оберните текст в промежуток и используйте ширину jquery ()

т.е. поместите его в элемент и измерьте его ширину... вы можете где-нибудь сделать это за кадром / удалить его после того, как достаточно быстро его никто не увидит, но это, вероятно, займет довольно много строк JavaScript! (Я мог бы исследовать это больше после работы...)

Причина, по которой вы не можете выровнять ширину без ее рендеринга, связана с различными типами и размерами шрифта, с которыми она может быть представлена. Так что, если вы всегда используете точный тип шрифта и размер шрифта, вы можете написать функцию, которая делает это без его рендеринга.

Поскольку готовых решений, похоже, нет, я написал относительно простую функцию jQuery, которая делает то, что я хочу. Вот если кто-то другой ищет его.

Это работает путем клонирования элемента, который мы хотим настроить. Клон скрыт, чтобы предотвратить его мигание при вводе в DOM. Затем мы делаем клон более узким, по одному пикселю за раз, пока он не обернется. Ширина прямо перед этим устанавливается на исходный элемент, а элемент-клон удаляется.

Лучшие способы достижения этого все еще приветствуются, так же как и предложения по улучшению этого. Codepen доступен здесь: http://codepen.io/Kaivosukeltaja/pen/jWYqZN

function adjust() {
  $('.quote').each(function() {
    // Create an invisible clone of the element
    var clone = $(this).clone().css({
      visibility: 'hidden',
      width: 'auto'
    }).appendTo($(this).parent());
    
    // Get the bigger width of the two elements to be our starting point
    var goodWidth = Math.max($(this).width(), $(clone).width());
    var testedWidth = goodWidth;
    var initialHeight = $(clone).height();

    // Make the clone narrower until it wraps again, causing height to increase
    while($(clone).height() == initialHeight && testedWidth > 0) {
      goodWidth = testedWidth;
      testedWidth--;
      $(clone).width(testedWidth);
    }

    // Set original element's width to last one before wrap
    $(this).width(goodWidth);
    
    // Remove the clone element
    $(clone).remove();
  });
}

$(window).resize(adjust);
$(document).ready(function() {
  adjust();
});
body {
  background-color: #f0f0f0;
}

.holder {
  text-align: center;
  margin: 2em auto;
}
.quote {
  display: inline-block;
  border: 1px solid #c0c0c0;
  background-color: #fff;
  padding: 1em;
  font-size: 40px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="holder">
  <div class="quote">
    If I want text to wrap, I want the lines as close to equal length as possible.
  </div>
</div>

Я создал пример с text-align: justify и без text-align: justify.

Посмотри на:

    .center {width:200px; float:left; margin-left: 20px;}
    .justify { text-align: justify; }
      
 
    <!-- 4. -->
    <section class="center">
      <p class="justify">orem ipsum dolor sit amet, consectetur adipisici elit, sed eiusmod tempor incidunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquid ex ea commodi consequat. Quis aute iure reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint obcaecat cupiditat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
    </section>
    <section class="center">
      <p class="">orem ipsum dolor sit amet, consectetur adipisici elit, sed eiusmod tempor incidunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquid ex ea commodi consequat. Quis aute iure reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint obcaecat cupiditat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
    </section>

Вы можете поместить текст в div и использовать свойства css ширины и text-align.

HTML:

<div id="center">This is an example of a piece of text that will wrap to two lines.This is an example of a piece of text that will wrap to two
lines.</div>

CSS:

#center{
  width : 100px;
  text-align : justify;
}

Я боюсь, что нет никакого способа сделать это в CSS, поэтому я просто искал его и нашел его здесь: /questions/35232495/razbit-bolshuyu-stroku-na-kuski-n-razmera-v-javascript И counting-words-in-string

Я собираюсь принять это как вызов и написать функцию для него:)

попробуйте переопределить количество слов и найдите длину, равную половине этого:

function chunkString(str, length) {
  length = length/2;
  return str.match(new RegExp('.{1,' + length + '}', 'g'));
}

.....

text-align: justify, Я не уверен, правильно ли я понял вопрос, но, глядя на вашу репутацию, я боюсь на это ответить!!:)

поместите текст в ap или span, убедитесь, что это display: block, inline-block сделаю работу также. Ширина каждого элемента должна составлять 50% от родительского элемента. затем text-align: justify дочерний элемент.

Вы можете использовать родительский тег, такой как DIV, и стиль с шириной =50%. Это сделало бы текст в больше строк.

Просто уменьшите ширину элемента, содержащего этот текст.

https://jsfiddle.net/cqmwqgbj/

some code
Другие вопросы по тегам