動的な文字数に基づいてフォントサイズをレスポンシブにする純粋なCSS


298

これはJavaScriptでかなり簡単に解決できることは知っていますが、私は純粋なCSSソリューションにのみ関心があります。

常に固定divに収まるようにテキストを動的にサイズ変更する方法が必要です。次にマークアップの例を示します。

<div style="width: 200px; height: 1em; overflow: hidden;">
  <p>Some sample dynamic amount of text here</p>
</div>

emsでコンテナーの幅を指定し、font-sizeにその値を継承させることで、これが可能になると思いましたか?


1
わあ、待って。widthin emの指定は逆になります。それはwidthに依存しますfont-size。@JosephSilberそれはまさに私が考えたことです。
Ana

1
この質問に興味があります。単純なJavaScript関数を作成する代わりに、純粋なCSSソリューションを使用する動機は何ですか?
オースティンマリンズ2013年

22
問題は単に存在し、純粋なCSSソリューションがすばらしいものであるという理由だけです。いくつかのスタイルを適用する可能性について考え、動的コ​​ンテンツがデザインを壊さないことを知ってください。
DMTintner 2013年

4
ただ、JSを使用して、この問題全体のケースの誰もつまずくとdoesntのを念頭に置いて、ここでそれを行うためのプラグインだfittextjs.comは
DMTintner

2
fitTextには制限があります。たとえば、幅が500pxを超える小さな画面でのみ実行したいので、見出しがこれ以上大きくならないようにします。これには、さらにJavaScriptを記述する必要があります。JavaScriptをレイアウトに使用すると、懸念事項の分離がすぐに壊れます。それは、迅速なワンライナーではありません。
コスタ

回答:


513

私はこれがVWユニットを使用して可能であることを知りました。これらは、ビューポートの幅の設定に関連する単位です。レガシーブラウザのサポートがないなど、いくつかの欠点がありますが、これは間違いなく使用を真剣に検討すべきものです。さらに、次のような古いブラウザにもフォールバックを提供できます。

p {
    font-size: 30px;
    font-size: 3.5vw;
}

http://css-tricks.com/viewport-sized-typography/ および https://medium.com/design-ux/66bddb327bb1


30
この1つの2アップを与えるでしょう。勝利のためのCSSソリューション!
Mihkel L. 14

34
プロのヒント:テキストを小さくしすぎないようにし、font-size:calc(100% + 2vw);同様の操作を行うことで、ある程度の制御を取り戻せます。ちょっとmin-font-sizeです。のブラウザサポートcalcはに似ていvwます。
Prinzhorn 2014年

116
賛成ですが、これが実際に元の質問に答えているのか疑問に思っています。私の理解では、テキストの長さは動的であり、フォントサイズを常にdiv(200px)の幅に合わせて変更したいと考えています。これはどのようにその問題を解決しますか?
フローレミン2015

26
@Floreminの意見に同意します。これは、テキストの幅/高さのコンテナではなく、ビューポートの幅/高さに基づいてすべてのフォントサイズをスケーリングします。
MickJuice 2015年

24
@Floreminは正しい、これは質問に対処していません。これは、コンテナの幅に関連する文字列の長さの関数としてではなく、コンテナの幅の関数としてfont-sizeを計算します
ヘンリー

113

CSS3は、ビューポートに関連する新しい寸法をサポートしています。しかし、これはAndroid <4.4では機能しません

  1. 3.2vw =ビューポートの幅の3.2%
  2. 3.2vh =ビューポートの高さの3.2%
  3. 3.2vmin = 3.2vwまたは3.2vhの小さい方
  4. 3.2vmax = 3.2vwまたは3.2vhの大きい方

    body
    {
        font-size: 3.2vw;
    }

参照css-tricks.com /を....とも見て.... caniuse.com /

または

メディアクエリを使用します。最も簡単な方法は、%またはemでディメンションを使用することです。基本フォントサイズを変更するだけで、すべてが変更されます。

@media (max-width: @screen-xs) {
    body{font-size: 10px;}
}

@media (max-width: @screen-sm) {
    body{font-size: 14px;}
}


h5{
    font-size: 1.4em;
}

%またはemの次元を使用ます。基本フォントサイズを変更するだけで、すべてが変更されます。以前のバージョンでは、毎回h1ではなくボディフォントを変更するか、ベースフォントサイズをデバイスのデフォルトにしてすべてをemに置くことができました

em、px、%の詳細については、kyleschaeffer.com / ....を参照してください


12
質問は、ビューポート全体ではなく、コンテナを基準にしたスケーリングに関するものでした。
Arnaud Weil、

6
...そして質問は、文字数に基づいたスケーリングに関するものでした
Bravo


14

おそらく唯一の方法は、異なる画面サイズに異なる幅を設定することですが、このアプローチはかなり不正確であり、jsソリューションを使用する必要があります。

h1 {
    font-size: 20px;
}

@media all and (max-device-width: 720px){
    h1 {
        font-size: 18px;
    }
}

@media all and (max-device-width: 640px){
    h1 {
        font-size: 16px;
    }
}

@media all and (max-device-width: 320px){
    h1 {
        font-size: 12px;
    }
}

12

私は長い間死んでいる質問を救済していることを知っていますが、同じ質問があり、何かを追加したいと思いました。これを禁止しないでください。この答えを正当化することが十分に重要であると感じました。必要に応じて削除します。@Joseph Silberは間違っています。すべての可能性をコーディングすることは、実際にこれを行うための実行可能な方法です。その理由は、実際には無限の可能性がないからです。まあ、技術的にはありますが、ビジターの99%が標準解像度を使用します。ほとんどのモバイルOSはアプリをフルスクリーンで実行し、ウィンドウのサイズを変更しないため、これはモバイルにも当てはまります(レスポンシブWebデザインの主な理由)。

また、スクロールバーのため、高さはほとんど関係ありません(ある程度、長さが4フィートまたは5フィートを超えるWebページをすぐに残しますが、これはほとんどの場合当てはまります)。そのため、幅についてのみ心配する必要があります。実際にコーディングする必要があるのは、240、320、480(古いiThingsの場合)、640、800、1024、1280、1440、1600、1920、2048、2560だけです。 4k、それはあなたのイメージを膨らませすぎ、100%幅に引き伸ばされた2560サイズは4kモニターでうまく見えます(私はこれをテストしました)。また、前のポスターが示唆したように720(720x480)を気にしないでください。その解像度はデジタルカメラでほぼ独占的に使用されており、それでも非常に一般的ではありません。

誰かがエキゾチックな解像度を使用している場合、過去15年間に作成されたほぼすべてのレンダラーが切り捨てられるため、誰かの画面の幅がそうであれば、1100、1024 CSSルールをロードするため、サイトが壊れることはありません。これにより、レスポンシブルールを作成しようとすることによるエキゾチックな解像度の説明が不要になり、Webブラウザーを使用してサイトがおそらく読み込まれないほど古くなっていない限り、可能なすべての設定をピクセルごとにコーディングする必要があるという考えはばかげています。とにかくすべて。


1
そして今、iPhone
6/6

SASSまたはコンパスを使用して関数に入ると、潜在的にさらに簡単になります。関数は、CSSが機能するすべてのことを実行できます。一度だけの書き込みが多い。
cjbarth 2017年

あなたはその側の装置90º、ターンまでの高さはかなり無関係です
Carvoロコ

これはコンテナの幅とは何の関係もありません-簡単に無限の可能性があります。
mcheah

8

参考までに、CSS以外のソリューション:

以下は、コンテナ内のテキストの長さに応じてフォントのサイズを変更するいくつかのJSです。

コードペンを少し変更したコードペンですが、以下と同じ考え方です。

function scaleFontSize(element) {
    var container = document.getElementById(element);

    // Reset font-size to 100% to begin
    container.style.fontSize = "100%";

    // Check if the text is wider than its container,
    // if so then reduce font-size
    if (container.scrollWidth > container.clientWidth) {
        container.style.fontSize = "70%";
    }
}

私にとっては、ユーザーがドロップダウンで選択を行ったときにこの関数を呼び出し、メニューのdivにデータが入力されます(ここに動的テキストが表示されます)。

    scaleFontSize("my_container_div");

さらに、CSSの省略記号( "...")を使用して、次のようにさらに長いテキストを切り詰めます。

#my_container_div {
    width: 200px; /* width required for text-overflow to work */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

つまり、最終的に:

  • 短いテキスト:例 "APPLES"

    完全にレンダリングされた素敵な大きな文字。

  • 長いテキスト:例:「リンゴとオレンジ」

    上記のJSスケーリング関数を使用して、70%に縮小されます。

  • 超長いテキスト:例:「リンゴとオレンジとバナ...」

    上記のJSスケーリング関数とCSSルールを使用して、70%に縮小され、「...」の省略記号で切り捨てられます。

また、同じフォントサイズを維持しながら、CSSの文字間隔を調整してテキストを狭くすることもできます。


ユーザーが純粋なCSSソリューションを求めていたため、反対票を投じました
AnotherLongUsername '11 / 11/19

2

多くの人が@DMTinterの投稿へのコメントで述べたように、OPは変更する文字の数(「量」)について尋ねていました。彼はCSSについても尋ねていましたが、@ Alexanderが示したように、「CSSだけでは不可能です」。私の知る限りでは、現時点ではそうであるように思われるので、人々が次に良いことを知りたがるのも当然のようです。

私はこれを特に誇りに思うわけではありませんが、うまくいきます。それを達成するための過剰な量のコードのようです。これがコアです:

function fitText(el){
  var text = el.text();
  var fsize = parseInt(el.css('font-size'));
  var measured = measureText(text, fsize);

  if (measured.width > el.width()){
    console.log('reducing');
    while(true){
      fsize = parseInt(el.css('font-size'));
      var m = measureText(text, fsize );
      if(m.width > el.width()){
        el.css('font-size', --fsize + 'px');
      }
      else{
        break;
      }
    }
  }
  else if (measured.width < el.width()){
    console.log('increasing');
    while(true){
      fsize = parseInt(el.css('font-size'));
      var m = measureText(text, fsize);
      if(m.width < el.width()-4){ // not sure why -4 is needed (often)
        el.css('font-size', ++fsize + 'px');
      }
      else{
        break;
      }
    }
  }
}

ここにJSビンがあります:http : //jsbin.com/pidavon/edit?html,css,js,console,output
可能な改善を提案してください(私はキャンバスを使用してテキストを測定することに本当に興味がないようです...らしいオーバーヘッドが多すぎる(?))。

measureText関数について@Peteに感謝:https ://stackoverflow.com/a/4032497/442665


2

この解決策も役立つかもしれません:

$(document).ready(function () {
    $(window).resize(function() {
        if ($(window).width() < 600) {
            $('body').css('font-size', '2.8vw' );
        } else if ($(window).width() >= 600 && $(window).width() < 750) {
            $('body').css('font-size', '2.4vw');
        } 
         // and so on... (according to our needs)
        } else if ($(window).width() >= 1200) {
            $('body').css('font-size', '1.2vw');
        }
    }); 
  });

うまくいきました!


これはどのようにワードラップを考慮に入れますか?
Leif Neland


2
calc(42px + (60 - 42) * (100vw - 768px) / (1440 - 768));

この方程式を使用します。

1440および768よりも大きいか小さい場合は、静的な値を指定するか、同じアプローチを適用できます。

vwソリューションの欠点は、縮尺率を設定できないことです。たとえば、画面解像度1440で5vwが60pxフォントサイズ(アイデアのフォントサイズ)になるかもしれませんが、ウィンドウ幅を768に縮小すると、最終的に12pxで、必要な最小サイズではありません。このアプローチを使用すると、上限と下限を設定でき、フォントはその間に自動的に拡大縮小されます。


-2

内の文字列の長さに基づいてフォントサイズを計算するルックアップテーブルを作成します<div>

const fontSizeLookupTable = () => {
  // lookup table looks like: [ '72px', ..., '32px', ..., '16px', ..., ]
  let a = [];
  // adjust this based on how many characters you expect in your <div>
  a.length = 32;
  // adjust the following ranges empirically
  a.fill( '72px' ,     );
  a.fill( '32px' , 4 , );
  a.fill( '16px' , 8 , );
  // add more ranges as necessary
  return a;
}

const computeFontSize = stringLength => {
  const table = fontSizeLookupTable();
  return stringLength < table.length ? table[stringLength] : '16px';
}

経験的テストにより、すべてのパラメーターを調整および調整します。


パラメータの経験的テストは、基本的に時間の複雑さを伴うバイナリ検索です:O(log n)。
私についてそれを

あなたは実際にこの関数を呼び出すのを忘れており、配列の長さもそのプロパティでアクセスする必要があります。
lukk

@lukk:フィードバックをありがとう。今それを修正しました。
私についてそれを
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.