拉伸文本以适合div的宽度

时间:2011-05-12 09:56:02

标签: html css

我有一个固定宽度的div,但div内的文字可以改变。

有没有办法用css或其他方式设置字母之间的间距,这样文字总能完美地填充div?

13 个答案:

答案 0 :(得分:31)

正如马克所说,text-align:justify;是最简单的解决方案。但是,对于简短的文字,它不会产生任何影响。以下jQuery代码将文本拉伸到容器的宽度。

它计算每个字符的空间并相应地设置letter-spacing,以便文本扩展到容器的宽度

如果文字太长而无法容纳在容器中,它会让它扩展到下一行并将text-align:justify;设置为文本。

以下是演示:



$.fn.strech_text = function(){
    var elmt          = $(this),
        cont_width    = elmt.width(),
        txt           = elmt.html(),
        one_line      = $('<span class="stretch_it">' + txt + '</span>'),
        nb_char       = elmt.text().length,
        spacing       = cont_width/nb_char,
        txt_width;
    
    elmt.html(one_line);
    txt_width = one_line.width();
    
    if (txt_width < cont_width){
        var  char_width     = txt_width/nb_char,
             ltr_spacing    = spacing - char_width + (spacing - char_width)/nb_char ; 
  
        one_line.css({'letter-spacing': ltr_spacing});
    } else {
        one_line.contents().unwrap();
        elmt.addClass('justify');
    }
};


$(document).ready(function () {
    $('.stretch').each(function(){
        $(this).strech_text();
    });
});
&#13;
p { width:300px; padding: 10px 0;background:gold;}
a{text-decoration:none;}

.stretch_it{ white-space: nowrap; }
.justify{ text-align:justify; }

.one{font-size:10px;}
.two{font-size:20px;}
.three{font-size:30px;}
.four{font-size:40px;}
.arial{font-family:arial;}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p class="stretch one">Stretch me</p>
<p class="stretch two">Stretch me</p>
<p class="stretch three">Stretch <a href="#">link</a></p>
<p class="stretch two">I am too slong, an I would look ugly if I was displayed on one line so let me expand to several lines and justify me.</p>
<p  class="stretch arial one">Stretch me</p>
<p class="stretch arial three">Stretch me</p>
<p class="stretch arial four">Stretch me</p>
<p class="arial two">Don't stretch me</p>
&#13;
&#13;
&#13;

Js fiddle demo

答案 1 :(得分:24)

这可以通过text-align:justify和一个小黑客来完成。见这里:http://codepen.io/aakilfernandes/pen/IEAhF/

诀窍是在假装长字的文本之后添加一个元素。假单词实际上是一个span元素display:inline-blockwidth:100%

在我的例子中,假单词为红色,高度为1em,但即使没有它,黑客也会有效。

答案 2 :(得分:8)

也许这可能会有所帮助:

text-align:justify;

答案 3 :(得分:6)

我发现短于一行的文本有更好的解决方案,没有任何额外的js或标记,只有一个类。

.stretch{ 
  /* We got 2rem to stretch */
  width: 5rem;
  /* We know we only got one line */
  height: 1rem;
  
  text-align: justify; 
}
.stretch:after{
    /* used to stretch word */
    content: '';
    width: 100%;
    display: inline-block; 
}
<div class="stretch">你好么</div>
<div class="stretch">你好</div>

答案 4 :(得分:4)

更简单的HTML / CSS方法是使用flexbox。 它也立即响应。但值得注意的是,如果你将它用作h1或其他东西,SEO就不会捡到它。

HTML:

<div class="wrapper">
<div>H</div>
<div>e</div>
<div>l</div>
<div>l</div>
<div>o</div>
<div>&nbsp</div>
<div>W</div>
<div>o</div>
<div>r</div>
<div>l</div>
<div>d</div>

CSS:

.wrapper{
  width: 100%;
  text-align: center;
  display: flex;
  flex-flow: row nowrap;
  justify-content: space-between;
  border: 1px solid black;
}

jsfiddle here

答案 5 :(得分:2)

上面的某些答案效果很好,但文本必须包含许多子元素 div
还有很多额外的代码。
div 中的文本应该干净,因此我借助JS做到了。

const words = document.querySelector(".words"),
  wordsArray = words.innerText.split("").map(e => " " == e ? "<div>&nbsp</div>" : "<div>" + e + "</div>");
words.innerHTML = wordsArray.join("");
.words {
  width: 100%;
  text-align: center;
  display: flex;
  flex-flow: row nowrap;
  justify-content: space-between;
}
<div class="words">This is the demo text</div>

答案 6 :(得分:2)

晚了一点,但是对于简单的纯CSS实现,请考虑使用flexbox

h1.stretch {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
}
<h1 class="stretch">
  <span>F</span>
  <span>o</span>
  <span>o</span>
  <span>B</span>
  <span>a</span>
  <span>r</span>
</h1>

不确定是否将每个字母包装在span中(注意任何元素都会起作用)是否会与SEO混淆,但我想搜索引擎会从用于重要标记的innerHTML标签中剥离标签,例如(例如,知道SEO确认的人?)

答案 7 :(得分:1)

2018年3月 如果您在更新的时间内登陆这个问题......

我试图做OP所询问的但只用一个字,并发现以下成功:

1。使用<span>并设置css:span { letter-spacing: 0px; display:block}        (这使元素只与内容一样宽)

2. 在加载时捕获范围let width = $('span').width();

的宽度

3。捕获范围let length = $('span').length;

的长度

4. 将范围的宽度重置为容器$('span').css({'width','100%'});

5. 捕获范围的新宽度(或仅使用容器宽度)let con = $('span').width();

6. 计算并设置字母间距以填充容器$('span').css({'letter-spacing':(cont-width)/length})

显然,这可以转换为使用vanilla js,即使对于大多数字体样式(包括非单字体字体)也很有用。

答案 8 :(得分:1)

使用我写的lineclamp module,您可以完成所需的工作。设置希望文本占用的最大行数或高度,它会找到适合该行数的最大字体大小,和/或修剪文本以使其适合。

import LineClamp from "//unpkg.com/@tvanc/lineclamp/dist/esm.min.js";

const clamp = new LineClamp(document.querySelector("#elementToClamp"), {
  useSoftClamp: true,
  // Set an arbitrarily high max font size. Default min is already 1
  maxFontSize: 10000,
  maxLines: 1
});

// .apply() to apply the clamp now
// .watch() to re-apply if content changes or window resizes
clamp.apply().watch();

工作示例:https://codepen.io/tvanc/pen/BaNmVXm


在问题中,OP说字母间距。在comment中,OP表示字母间距字体大小。

答案 9 :(得分:1)

如果有人对如何证明内容的合理性感兴趣,并且只将最后一行居中

text-align: justify;
text-align-last: center;

请参见示例:

.custom-justify{
   text-align: justify;
   text-align-last: center;
   padding: 0 10px 0 10px;
}
<div class="custom-justify">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis mollis elementum bibendum. Cras pellentesque sed augue nec lacinia. Duis at eros vel lorem cursus laoreet ac vel justo. Maecenas ornare, ligula ut porttitor sollicitudin, turpis urna auctor ipsum, a consectetur felis nibh vel est. Nullam id lorem sit amet magna mollis iaculis eu vitae mauris. Morbi tempor ut eros ut vulputate. Quisque eget odio velit. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Sed posuere enim tellus, ut vestibulum libero dapibus ac. Nulla bibendum sapien non luctus vehicula. Aenean feugiat neque nunc, in fermentum augue posuere vel. Maecenas vitae diam in diam aliquet aliquam.<div>

答案 10 :(得分:0)

我认为你真正想要的是缩放。

使用一些看起来很漂亮的分辨率渲染你的字体,然后使用JS通过使用css变换将其拉伸到容器中:

transform: scale(1.05);

这样做的好处是你的文字总是很有意思,但是你会遇到它变得太小而无法阅读的问题。

快速说明,您需要使您尝试缩小/扩展的元素具有绝对位置:

position: absolute;

答案 11 :(得分:0)

所以,仍然蚕食这个问题的边缘,如果你将wener&#39; answer that stretches short lines of text与来自另一个线程的suggestion to use a real element结合起来,你可以完成所有事情而不需要{{ 1}}伪类。

您在实际元素中替换并将放在之后您想要证明的元素。这将以相同的方式触发对齐:

&#13;
&#13;
:after
&#13;
header {
  background-color: #ace;
  text-align: justify;
}

.hack {
  display: inline-block;
  width: 100%;
}
&#13;
&#13;
&#13;

此变体允许您将此技巧与React和样式对象一起使用:

&#13;
&#13;
<header>
  <div>
    A line of text to justify
    <div class="hack"></div>
  </div>
</header>
&#13;
const style = {
  backgroundColor: '#ace',
  textAlign: 'justify'
};

const hack = {
  display: 'inline-block',
  width: '100%'
};

const example = (
  <header style={ style }>
    <div>
      A line of words to stretch
      <div style={ hack } />
    </div>
  </header>
);

ReactDOM.render(example, document.getElementById('root'));
&#13;
&#13;
&#13;

这已经足够丑陋和hacky,但是从那里你必须以你想要的方式选择你的毒药&#34;修复&#34;容器的多余高度:容器的固定高度或负边距?以下元素的相对定位和重叠?将容器背景与页面背景相匹配,并假装额外的保证金是有意的吗?

答案 12 :(得分:-3)

jsfiddle link

对于纯HTML / CSS解决方案,当您处理更短的文本时(足够短

text-align: justify;

不起作用)

我跟随this great post作为灵感,并将每个字母放在div中

HTML:

<div class="wrapper">
    <div class="letters">H</div>
    <div class="letters">e</div>
    <div class="letters">l</div>
    <div class="letters">l</div>
    <div class="letters">o</div>
    <div class="letters">&nbsp</div>
    <div class="letters">W</div>
    <div class="letters">o</div>
    <div class="letters">r</div>
    <div class="letters">l</div>
    <div class="letters">d</div>
    <span class="stretch"></span>
</div>

CSS:

.wrapper {
    width: 300px; /*for example*/
    border: 1px solid gray; /*only for demonstrative purposes*/
    text-align: justify;
    -ms-text-justify: distribute-all-lines;
    text-justify: distribute-all-lines;
}

.letters {
    vertical-align: top;
    display: inline-block;
    *display: inline;
    zoom: 1
}

.stretch {
    width: 100%;
    display: inline-block;
    font-size: 0;
    line-height: 0
}