web-dev-qa-db-ja.com

CSSテキストは文字間隔で正当化されます

CSSを使用して、各行の文字間隔を使用して定義された幅に単語を自動的に正当化する方法はありますか?

たとえば、「このようなもの」は、次のようになります。

"Something like this" would look something like this

そのようなスタイルを私のテキストに適用する邪魔にならない方法はありますか?純粋なCSSにはこのオプションがないと思います(少なくとも3より前のCSSバージョンでは、CSS3にはtext-justifyプロパティがあるようですが、まだ十分にサポートされていません)。したがって、jsソリューションでも問題ありません。

27
Groo

これがそれを実行できるスクリプトです。きれいではありませんが、ニーズに合わせてハックすることができます。 (サイズ変更を処理するように更新)

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>
11
Dark Falcon

Cssのみのソリューションはtext-justify: distributehttps://www.w3.org/TR/css-text-3/#text-justify ですが、サポートはまだ非常に貧弱です。

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>
6
PoseLab

私はこれが古いトピックであることを知っています、しかし私は先日これに直面しました。そして、テーブルを使用して適切な解決策を見つけました。

すべての文字は<td> </td>に入れられます。退屈に見えることは知っていますが、これを実行したい場合は、1〜2語で構いません。または、多すぎる場合はいつでもJSを使用して入力できます。ただし、これはCSSであり、非常に用途の広いソリューションです。

文字間隔を使用すると、文字が適切に分散されます。テーブルの幅に応じて、それをいじってみてください。

#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>

ここの例を参照

クロスブラウザは安全で、事実上何も違いはありません。ただのCSSです。

私はそれを 私のウェブサイト で使用しました。これは英語とスペイン語です。スペイン語の私の名前の下のサブタイトルには追加の文字があり、幅が大きくなります。上で説明した表を使用して、同じ幅に自動的に分散されます。手動で間隔を空けるには、各言語がそれを回避するための全体的な条件を定義する必要がありました。

4
Tony B

これは、この質問のために書いたjQueryスニペットを使用した別のアプローチです: divの幅に合うようにテキストをストレッチします

[〜#〜]デモ[〜#〜]

HTML:

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

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();
    });
});
3
web-tiki

これも必要だったので、ここで見つけることができる使いやすいjquery-pluginに提案された手法をバンドルしました: https://github.com/marc-portier/jquery-letterjustify#readme

コアで同じ手順を使用し、Tweakにいくつかのオプションを追加します。コメントを歓迎します。

2
mpo

繰り返しますが、これは本当に古いことですが、各文字の間にスペースを入れてからtext-align:justifyを実行しないのはなぜですか?次に、各文字は「単語」と見なされ、それに応じて正当化されます

0
JBarnes

これを処理する別の方法は、「vw」サイジングユニットを使用することです。このユニットタイプは、フォントサイズのプロパティで使用でき、ウィンドウの幅のパーセントを表します。

免責事項:それはあなたが探しているものではありませんが、スクリプトを必要としません。テキストサイズを調整しますが、ページの幅に合わせて拡大縮小します。

例えば、

.heading {
  font-size: 4vw;
}

現在のフォントの1文字の幅がウィンドウ幅の4%になります。

次に、ウィンドウの幅に基づいてフォントサイズを最小サイズにロックする場合は、メディアクエリを使用できます。

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

ブラウザインスペクタを使用してfont-sizeプロパティを操作し、アプリケーションにとって意味のある値に調整します。

「vw」ユニットは、IE9 +、iOS 8.3 +、Android 4.4+、およびその他すべての主流のブラウザで動作します。メディアクエリを使用して、モバイルサポートについてあまり心配する必要はありません。上記のように、これらのデバイスに適切なサイズを設定します。

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

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

ビューポートユニットは、少ないコードでサイトのさまざまな側面を拡張するための強力な方法です。

0
Neil Monroe

テーブルのTonyBアプローチからJQueryスクリプトを作成しました。これがJSFiddleです https://jsfiddle.net/7tvuzkg3/7/

このスクリプトは、各文字が連続したテーブルを作成します。これは全文で機能します。これが完全に最適化されているかどうかはわかりません。

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>
0
Lucas Tesseron