【问题标题】:Shrink DIV to text that's wrapped to its max-width?将 DIV 缩小到包装到最大宽度的文本?
【发布时间】:2013-01-30 03:31:01
【问题描述】:

将 div 收缩到一些文本非常简单。但是,如果文本由于最大宽度(例如)而换行到第二行(或更多),则 DIV 的大小不会缩小到新换行的文本。它仍然扩展到断点(在本例中为 max-width 值),从而在 DIV 的右侧产生了相当多的边距。当想要将此 DIV 居中以使换行的文本居中时,这是有问题的。不会,因为 DIV 不会缩小为换行的多行文本。一种解决方案是使用两端对齐的文本,但这并不总是可行的,而且如果单词之间的间隔很大,结果可能会很糟糕。

我知道没有解决方案可以将 DIV 缩小为纯 CSS 中的换行文本。所以我的问题是,如何使用 Javascript 实现这一目标?

这个 jsfiddle 说明了它:jsfiddle。由于最大宽度,这两个单词几乎没有换行,但 DIV 并没有缩小到新换行的文本,留下了令人讨厌的右侧边距。我想消除这一点,并大概使用 Javascript 将 DIV 调整为包装文本(因为我不相信纯 CSS 中存在解决方案)。

.shrunken {text-align: left; display: inline-block; font-size: 24px; background-color: #ddd; max-width: 130px;}

<div class="shrunken">Shrink Shrink</div>

【问题讨论】:

  • 一些图像演示或代码示例(jsfiddle?)将有助于理解和构建您的意思。
  • 这没有解决什么问题? jsfiddle.net/uS6cf/1
  • 为什么文本必须换行时 div 不缩小(您的最大宽度示例)?只是为了获得有关此问题的更多信息,您如何缩小 div?
  • @isherwood 这实际上完美地说明了这个问题。这两个词强制中断,但 DIV 仍处于其最大宽度 130 像素,而最大的词小于 130 像素,从而在左侧和右侧创建边距。我希望 DIV 缩小到最大的换行文本。对示例中的文本使用“Shrink Shrink”会使其更加明显。

标签: javascript html css


【解决方案1】:

这不是最漂亮的解决方案,但应该可以解决问题。逻辑是计算每个单词的长度,并用它来计算在强制换行之前最长的行是多少;然后将该宽度应用于div。在这里摆弄:http://jsfiddle.net/uS6cf/50/

示例 html...

<div class="wrapper">
    <div class="shrunken">testing testing</div>
</div>

<div class="wrapper">
    <div class="shrunken fixed">testing testing</div>
</div>

<div class="wrapper">
    <div class="shrunken">testing</div>
</div>

<div class="wrapper">
    <div class="shrunken fixed">testing</div>
</div>

<div class="wrapper">
    <div class="shrunken" >testing 123 testing </div>
</div>

<div class="wrapper">
    <div class="shrunken fixed" >testing 123 testing </div>
</div>

还有javacript(依赖jQuery)

$.fn.fixWidth = function () {
    $(this).each(function () {
        var el = $(this);
        // This function gets the length of some text
        // by adding a span to the container then getting it's length.
        var getLength = function (txt) {
            var span = new $("<span />");
            if (txt == ' ')
                span.html('&nbsp;');
            else
                span.text(txt);
            el.append(span);
            var len = span.width();
            span.remove();
            return len;
        };
        var words = el.text().split(' ');
        var lengthOfSpace = getLength(' ');
        var lengthOfLine = 0;
        var maxElementWidth = el.width();
        var maxLineLengthSoFar = 0;
        for (var i = 0; i < words.length; i++) {
            // Duplicate spaces will create empty entries.
            if (words[i] == '')
                continue;
            // Get the length of the current word
            var curWord = getLength(words[i]);
            // Determine if adding this word to the current line will make it break
            if ((lengthOfLine + (i == 0 ? 0 : lengthOfSpace) + curWord) > maxElementWidth) {
                // If it will, see if the line we've built is the longest so far
                if (lengthOfLine > maxLineLengthSoFar) {
                    maxLineLengthSoFar = lengthOfLine;
                    lengthOfLine = 0;
                }
            }
            else // No break yet, keep building the line
                lengthOfLine += (i == 0 ? 0 : lengthOfSpace) + curWord;
        }
        // If there are no line breaks maxLineLengthSoFar will be 0 still. 
        // In this case we don't actually need to set the width as the container 
        // will already be as small as possible.
        if (maxLineLengthSoFar != 0)
            el.css({ width: maxLineLengthSoFar + "px" });
    });
};

$(function () {
    $(".fixed").fixWidth();
});

【讨论】:

  • 感谢您理解问题并提供解决方案。我会尽快对此进行测试并报告。
  • 我认为在您发生换行的情况下 (lengthOfLine = 0),它需要将其设置为 curWord 的长度。否则这个词是下落不明的,它可以摆脱包装和maxLineLengthSoFar
  • 另外,getLength 将 txt 附加到现有内容。如果 span 换行(例如,如果 txt 的值是一个连字符),则 span 的宽度会增长以适应其在两行之间拆分的内容。我解决了这个问题,首先使用 var originalContents = el.contents().detach() 从 el 中删除内容,然后在删除跨度后将 originalContents 附加回 el。我分叉了显示这些场景的小提琴,并为它们提供了建议的修复:jsfiddle.net/t333d96f/2
  • 2021 年 - 现在有没有 CSS 解决方案?我真的不想用js做这个
【解决方案2】:

我有点晚了,但我认为这段 CSS 代码对其他有同样问题的用户很有用:

div {
  width: -moz-min-content;
  width: -webkit-min-content;
  width: min-content;
}

【讨论】:

  • 这会导致内容在每个可能的断点处换行,效果不同。
【解决方案3】:

我猜这就是你的想法,可以在css中完成:

div {
    border: black solid thin;
    max-width: 100px;
    overflow: auto;
}

你可以在这里看到它:http://jsfiddle.net/5epS4/

【讨论】:

  • 您只是碰巧选择了一个因溢出而遮挡右边距的最大宽度。使用 200px 更能说明问题。
  • 啊...所以你的意思是父 div 也应该包装到它的子 div?我认为在你的包装器 div 上添加 display: inline-block; 可以解决你的问题,如果我没有误解你想要发生的事情......在这里查看jsfiddle.net/QrP4k
  • 不。我只是想让包含文本的 DIV 收缩到它,即使它由于最大宽度而包裹了文本。
【解决方案4】:

试试这个: https://jsfiddle.net/9snc5gfx/1/

.shrunken {
   width: min-content;
   word-break: normal;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-27
    • 1970-01-01
    • 2020-11-13
    • 1970-01-01
    • 1970-01-01
    • 2020-12-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多