CSS 文本对齐字母间距

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4355009/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 23:15:32  来源:igfitidea点击:

CSS text justify with letter spacing

cssjustifyletter-spacingtext-justify

提问by Groo

Is there a way to automatically justify words using letter spacing, each in its row, to a defined width, using CSS?

有没有办法使用 CSS 使用字母间距自动对齐单词,每个单词在其行中,以定义的宽度?

For example, "Something like this" would look, well, something like this:

例如,“像这样的东西”看起来像这样:

"Something like this" would look something like this

“像这样的东西”看起来像这样

Is there a non-obtrusive way to apply such styling to my text? I believe pure CSS doesn't have this option (at least not with CSS versions before 3, CSS3 seems to have a text-justifyproperty, but it's not well supported yet), so js solutions would be fine also.

是否有一种非侵入式的方式将这种样式应用于我的文本?我相信纯 CSS 没有这个选项(至少在 3 之前的 CSS 版本没有,CSS3 似乎有一个text-justify属性,但它还没有得到很好的支持),所以 js 解决方案也可以。

采纳答案by Dark Falcon

Here's a script which can do it. It isn't pretty, but maybe you can hack it to meet your needs. (Updated to handle resizing)

这是一个可以做到这一点的脚本。它并不漂亮,但也许您可以破解它以满足您的需求。(更新以处理调整大小)

function SplitText(node) {
  var text = node.nodeValue.replace(/^\s*|\s(?=\s)|\s*$/g, "");

  for (var i = 0; i < text.length; i++) {
    var letter = document.createElement("span");
    letter.style.display = "inline-block";
    letter.style.position = "absolute";
    letter.appendChild(document.createTextNode(text.charAt(i)));
    node.parentNode.insertBefore(letter, node);

    var positionRatio = i / (text.length - 1);
    var textWidth = letter.clientWidth;

    var indent = 100 * positionRatio;
    var offset = -textWidth * positionRatio;
    letter.style.left = indent + "%";
    letter.style.marginLeft = offset + "px";

    //console.log("Letter ", text[i], ", Index ", i, ", Width ", textWidth, ", Indent ", indent, ", Offset ", offset);
  }

  node.parentNode.removeChild(node);
}

function Justify() {
  var TEXT_NODE = 3;
  var elem = document.getElementById("character_justify");
  elem = elem.firstChild;

  while (elem) {
    var nextElem = elem.nextSibling;

    if (elem.nodeType == TEXT_NODE)
      SplitText(elem);

    elem = nextElem;
  }
}
#character_justify {
  position: relative;
  width: 40%;
  border: 1px solid red;
  font-size: 32pt;
  margin: 0;
  padding: 0;
}

#character_justify * {
  margin: 0;
  padding: 0;
  border: none;
}
<body onload="Justify()">
  <p id="character_justify">
    Something<br/> Like
    <br/> This
  </p>
</body>

回答by PoseLab

The css only solution is text-justify: distributehttps://www.w3.org/TR/css-text-3/#text-justifybut the support is still very poor.

css 唯一的解决方案是text-justify: distributehttps://www.w3.org/TR/css-text-3/#text-justify但支持仍然很差。

A small experiment using text-align-last: justifyand adding spaces between letters.

text-align-last: justify在字母之间使用和添加空格的小实验。

div{
 display:inline-block;
 text-align: justify;
 text-align-last: justify;
 letter-spacing: -0.1em;
}
<div>
S o m e t h i n g<br>
l i k e<br>
t h i s
</div>

回答by Tony B

I know this is an old topic, but I faced this the other night. And found a suitable solution using tables.

我知道这是一个古老的话题,但前几天晚上我遇到了这个问题。并使用表格找到了合适的解决方案。

Every letter shall be put into a <td> </td>I know it looks tedious, but if you wanna do this, it would be for a word or two, right? Or you always can use JS to fill it if is too much. However, this is only CSS and very versatile solution.

每个字母都应该放入一个<td> </td>我知道这看起来很乏味,但如果你想这样做,只需要一两个字,对吧?或者你总是可以使用JS来填充它如果太多。然而,这只是 CSS 和非常通用的解决方案。

Using letter-spacing the letters get distributed properly. You should play around with it, depending on the width of the table.

使用字母间距可以正确分配字母。你应该玩弄它,这取决于桌子的宽度。

#justify {
  width: 300px;
  letter-spacing: 0.5em;
}
<table id="justify">
  <tbody>
    <tr>
      <td>J</td>
      <td>U</td>
      <td>S</td>
      <td>T</td>
      <td>I</td>
      <td>F</td>
      <td>Y</td>
    </tr>
  </tbody>
</table>

See the example here

请参阅此处的示例

Crossbrowser safe, virtually nothing shall differ. Is just CSS.

跨浏览器安全,几乎没有什么不同。只是CSS。

I used it in My websitewhich is in english and spanish. the subtitle under my name in spanish has an additional letter and it will step out the width. Using the tables explained above, it gets distributed to the same width automatically. Spacing it manually I'd had to define a whole condition for each language to go around that.

我在我的英文和西班牙文网站中使用了它。我名字下的西班牙语副标题有一个额外的字母,它会超出宽度。使用上面解释的表格,它会自动分配到相同的宽度。手动间隔我不得不为每种语言定义一个完整的条件来解决这个问题。

回答by web-tiki

Here is an other aproach using a jQuery snippet I wrote for this question : Stretch text to fit width of div:

这是使用我为这个问题编写的 jQuery 片段的另一种方法:拉伸文本以适应 div 的宽度

DEMO

演示

HTML :

HTML :

<div class="stretch">Something</div>
<div class="stretch">Like</div>
<div class="stretch">This</div>

jQuery :

jQuery :

$.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();
    });
});

回答by mpo

Needed this too, so I've bundled the suggested technique in a simple to use jquery-plugin you can find here: https://github.com/marc-portier/jquery-letterjustify#readme.

也需要这个,所以我将建议的技术捆绑在一个简单易用的 jquery-plugin 中,你可以在这里找到:https: //github.com/marc-portier/jquery-letterjustify#readme

It uses the same procedure at its core, and adds some options to tweak. Comments welcome.

它的核心使用相同的程序,并添加了一些调整选项。欢迎评论。

回答by Neil Monroe

An alternate way to handle this might be to use the "vw" sizing unit. This unit type can be used in font size properties and represents a percent of the window's width.

处理此问题的另一种方法可能是使用“vw”大小调整单位。此单位类型可用于字体大小属性并表示窗口宽度的百分比。

Disclaimer:It is not exactly what you are looking for, but requires no scripting. It does adjust the text size, but will also scale to the width of your page.

免责声明:这不是您正在寻找的内容,但不需要编写脚本。它确实会调整文本大小,但也会缩放到页面的宽度。

For example,

例如,

.heading {
  font-size: 4vw;
}

will make the width of one character in the current font 4% of the window width.

将使当前字体中一个字符的宽度为窗口宽度的 4%。

You could then use media queries if you wish to lock the font size to a minimum size based on the window's width.

如果您希望根据窗口的宽度将字体大小锁定为最小大小,则可以使用媒体查询。

@media only screen and (max-width: 768px) {
    font-size: 2rem;
}

Use the browser inspector to play with the font-size property and tweak the value to what makes sense for your application.

使用浏览器检查器来使用 font-size 属性并将值调整为对您的应用程序有意义的值。

The "vw" unit works in IE9+, iOS 8.3+ and Android 4.4+ and all other mainstream browsers. I wouldn't worry about the mobile support too much, as you can use media queries to put the right sizing for these devices as described above.

“vw”单元适用于 IE9+、iOS 8.3+ 和 Android 4.4+ 以及所有其他主流浏览器。我不会太担心移动支持,因为您可以使用媒体查询为这些设备设置正确的大小,如上所述。

http://caniuse.com/#feat=viewport-units

http://caniuse.com/#feat=viewport-units

https://css-tricks.com/viewport-sized-typography/

https://css-tricks.com/viewport-sized-typography/

Viewport units are a powerful way to scale many different aspects of your site with little code.

视口单位是一种强大的方式,可以用很少的代码来扩展站点的许多不同方面。

回答by Lucas Tesseron

I just made a JQuery script from table's Tony B approach. Here is the JSFiddle https://jsfiddle.net/7tvuzkg3/7/

我刚刚从 table 的 Tony B 方法制作了一个 JQuery 脚本。这是 JSFiddle https://jsfiddle.net/7tvuzkg3/7/

This script creates a table with each char in a row. This works with full sentence. I'm not sure this is fully optimized.

此脚本创建一个表,其中包含一行中的每个字符。这适用于完整的句子。我不确定这是完全优化的。

justifyLetterSpacing("sentence");

function justifyLetterSpacing(divId) {

 // target element
 domWrapper = $('#' + divId).clone().html('');
 // construct <td>
 $('#' + divId).contents().each(function(index){
      // store div id to td child elements class
   var tdClass = divId ;
      // split text 
   $textArray = $(this).text().split('');
      // insert each letters in a <td>
   for (var i = 0; i < $textArray.length; i++) {
        // if it's a 'space', replace him by an 'html space'
        if( $textArray[i] == " " )  {
            $('<td>')
                .addClass(tdClass)
                .html("&nbsp;&nbsp;")
                .appendTo(domWrapper);
        }// if it's a char, add it
        else{  
            $('<td>')
                .addClass(tdClass)
                .text($textArray[i])
                .appendTo(domWrapper);
        }
   }
 });
    // create table
    table = 
    $( "<table id='"+divId+"'/>" ).append( 
        $( "<tbody>" ).append( 
            $( "<tr>" ).append( 
                ( domWrapper ).children('td') 
            ) 
        )
    );
    // replace original div
 $('#' + divId).replaceWith( table );
} 
#sentence {
  width : 100%;
  background-color : #000;
  color : #fff;
  padding : 1rem;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="sentence">LOREM IPSUM DOLOR</div>

回答by JBarnes

Again, I know this is REALLY old, but why not just put a space between each letter and then text-align:justify? Then each letter would be regarded as a 'word' and justified accordingly

同样,我知道这真的很旧,但为什么不在每个字母之间放一个空格然后 text-align:justify?然后每个字母将被视为一个“单词”并相应地合理化