如何将文本均匀分布在多行中?

32

我想显示一小段可能会换行两三行的文本内容。它位于一个高度可视的元素内,为了样式的目的,我希望这些行的长度尽可能相等,且更倾向于用一行而不是两行。

与其如下:

这是一个将换成两行的文本示例

我想要这个:

这是一个将换成两行的文本

示例。

但我不想限制文本容器的宽度:

这段文本足够长,只能在两行中刚好容纳。

它不应该换行为三行或更多行,因此不需要限制宽度。

是否有一种纯CSS或可接受的JavaScript方法可以实现?


我认为仅使用CSS是不可能的。需要像JavaScript / JQuery这样的脚本。 - ketan
你想如何处理当一个长单词恰好在应该换行的位置上的情况? - Ieuan Stanley
你尝试过在文本容器上使用 max-width 吗?你实际上尝试了什么?为什么不想限制文本容器? - Pogrindis
我正在编写一个简单的JavaScript函数……你对长单词有什么计划吗?它应该被拆分吗? - mehari
@Pogrindis:我还没有尝试过太多的东西,因为我所知道的唯一确定的方法是将文本拆分为span元素,计算它们的宽度,并在屏幕重新调整大小时手动添加换行符。我想先询问一下是否有更简单的解决方案。 @Bit:不需要对长单词进行特殊处理。只需注意字体是变宽的,因此我们无法仅通过文本就知道它们在屏幕上的宽度。 - Kaivosukeltaja
8个回答

26

4
在那成为事实之前,有这个... https://github.com/adobe-webplatform/balance-text - doublejosh
2
状态React 替代方案Svelte 替代方案 - M Imam Pratama

3

如果我理解你的问题(如果我理解的话,“使用对齐”这一主题并不完全适用),我认为你无法避免编写相当数量的 JavaScript。

我能想到的唯一方法是比较文本的宽度和容器的宽度,并进行相应的调整。

公式:单行文本宽度 = 文本宽度 / 四舍五入(文本宽度/容器宽度)

即,(可能需要一些调整以防止它截断单词)

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 width()将文本包装在span中,即将其放入元素中并测量其宽度......您可能能够在屏幕外执行此操作/快速删除它,以便没有人看到它,但这可能需要相当多的JavaScript代码!(下班后我可能会进一步调查这个问题......)
无法直接计算出宽度是由于它可以用各种字体类型和大小来表示。因此,如果您始终使用精确的字体类型和字体大小,则可能能够编写一个不需要渲染即可完成的函数。

是的,看起来你正确理解了我的问题。 :) 如果没有更简单的解决方案,你的伪代码示例看起来像一个合理的起点。 - Kaivosukeltaja

1

我创建了一个例子,其中包括使用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>


尝试删除第一段中 consectetur 一词后的所有内容。我希望这些行长度接近,但是实际上 consectetur 仍然独占一行。 - Kaivosukeltaja
好的,现在我明白你的问题了。这并不容易。我认为使用纯 CSS 是不可能的。原因是 CSS 需要计算字符串的中间位置才能将其分成两半。 - osanger

1

由于似乎没有现成的解决方案可用,我写了一个相对简单的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>


0

很抱歉,CSS中没有这样做的方法,所以我刚刚搜索了一下,在这里找到了在JavaScript中将大字符串拆分为n个块计算字符串中的单词数

我将把这视为一个挑战,并编写一个函数来解决它 :)

尝试使用正则表达式查找单词数并找到其一半长度,然后执行以下操作:

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

.....

text-align: justify

我不确定我是否理解了问题,但是看到您的声望,我害怕回答这个问题!:)

将文本放入 p 或 span 中,确保其为 display: blockinline-block 也可以胜任。每个元素的宽度应为父元素的 50%。然后对子元素进行 text-align: justify


我正在考虑提供一个JavaScript函数来包装这个...但是看他的声誉,我也有点害怕。 - mehari
哈哈哈,我也是这样,但这在 CSS 中是如此简单的一件事情,以至于我怀疑自己是否理解正确了!:) 文本对齐已经存在了很多年! - Daniel PurPur
1
被声誉吓倒是没有意义的,没有人知道所有的事情。 - Pogrindis
确切地说,没有必要因声望而感到害怕。我见过声望超过10k的人在他们之前不熟悉的主题上问非常基础的问题。不幸的是,我无法限制文本宽度,请查看我的更新第三个示例以了解原因。 - Kaivosukeltaja

0
你可以将文本放入一个 div 中,然后使用宽度和文本对齐的 CSS 属性:

#center{
  width : 100px;
  text-align : justify;
}
<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>


-1
你可以使用像DIV这样的父标签,并将其样式设置为width=50%。这将使文本显示在多行中。

-2

只需缩短包含此文本的元素的宽度:

div {
    width: 210px;
}
<div>This is an example of a piece of text that will wrap to two lines.</div>


请查看失败的示例 - 这些行应该具有相等的宽度或在单行上:https://jsfiddle.net/cqmwqgbj/3/ - Kaivosukeltaja

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接