30

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

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

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

4

10 に答える 10

13

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

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>

于 2010-12-04T19:06:33.170 に答える
9

cssのみのソリューションはtext-justify: distribute https://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>

于 2017-08-03T11:56:13.427 に答える
4

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

すべての手紙は<td> </td>退屈に見えることを私は知っていますが、あなたがこれをしたいのであれば、それは一言か二言ですよね?または、多すぎる場合は、いつでも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です。

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

于 2014-05-16T18:37:54.900 に答える
3

これは、この質問のために書いた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();
    });
});
于 2014-07-11T10:42:19.663 に答える
2

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

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

于 2014-09-14T18:47:44.987 に答える
0

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

于 2014-08-15T03:30:04.690 に答える
0

これを処理する別の方法は、「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/

ビューポートユニットは、わずかなコードでサイトのさまざまな側面を拡大縮小するための強力な方法です。

于 2015-04-30T23:39:42.287 に答える
0

テーブルのTonyBアプローチからJQueryスクリプトを作成しました。これがJSFiddlehttps ://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>

于 2016-02-27T14:56:16.453 に答える
0

純粋なCSSでこれを達成する別の方法を見つけました。残念ながら、単語を綴る必要があります。

私の状況では、これが機能した唯一の解決策でした(一部の文字にはクラスがありました)。さらに、ハックを使用せずに、ここでの回答の中で最もまっすぐな右揃えを生成しました。

.box {
  width: min-content;
  border: solid red;
}

.word {
  display: flex;
  justify-content: space-between;
}
<div class="box">
  <div class="word">
    <span>S</span>
    <span>o</span>
    <span>m</span>
    <span>e</span>
    <span>t</span>
    <span>h</span>
    <span>i</span>
    <span>n</span>
    <span>g</span>
    <span>&nbsp;</span>
    <span>w</span>
    <span>i</span>
    <span>c</span>
    <span>k</span>
    <span>e</span>
    <span>d</span>
  </div>

  <div class="word">
    <span>t</span>
    <span>h</span>
    <span>i</span>
    <span>s</span>
    <span>&nbsp;</span>
    <span>w</span>
    <span>a</span>
    <span>y</span>
  </div>

  <div class="word">
    <span>c</span>
    <span>o</span>
    <span>m</span>
    <span>e</span>
    <span>s</span>
  </div>
</div>

于 2020-07-21T16:45:36.783 に答える
0

私は通常、時間通りに答えを書こうとします。そしてこれはまったく同じ時間です(10年後)=)

myText.innerHTML = myText.textContent
    .split(/\s+/g)
    .map((line) => line.trim().split("").join(" "))
    .join("<br>");
#myText {
    display: inline-block;
    text-align: justify;
    text-align-last: justify;
    letter-spacing: -0.125em;
    font-family: sans-serif;
}
<div id="myText">Something like this</div>

于 2021-07-01T01:27:46.373 に答える