纯CSS使字体大小响应基于动态字符量

我知道这可以很容易地用Javascript解决,但我只对纯CSS解决方案感兴趣。

我想要一种动态调整文本大小的方法,以便它总是适合固定的div。下面是示例标记:

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

我在想,也许这可以通过在ems中指定容器的宽度,并获得字体大小继承该值?

569940 次浏览

唯一的方法可能是为不同的屏幕大小设置不同的宽度,但这种方法是非常不准确的,你应该使用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;
}
}

注意:此解决方案根据视口大小而不是内容的数量而更改

我刚刚发现这是可能的使用大众单位。它们是与设置视口宽度相关的单元。它有一些缺点,比如缺乏传统浏览器的支持,但这绝对是值得认真考虑的。另外,你仍然可以为旧的浏览器提供备份,如下所示:

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

http://css-tricks.com/viewport-sized-typography/ 而且 https://medium.com/design-ux/66bddb327bb1 < / p >

它与css中的钙()有关。将来你也许能做到。

不幸的是,目前没有css唯一的解决方案。这就是我建议你做的。给元素一个title属性。并使用文本溢出省略号来防止设计的破坏,让用户知道有更多的文本在那里。

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


另外,如果你只是想减少大小基于视口。CSS3支持相对于视图端口的新维度。

body {
font-size: 3.2vw;
}
  1. 3.2vw =视口宽度的3.2%
  2. 3.2vh =视口高度的3.2%
  3. 3.2vmin =小于3.2vw或3.2vh
  4. 3.2vmax = 3.2vw或3.2vh更大 参见css-tricks.com/..。caniuse.com/..。

正如许多人在@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 Bin: http://jsbin.com/pidavon/edit?html,css,js,console,output
请建议可能的改进(我不是真的对使用画布来测量文本感兴趣…看起来开销太大了(?)).

感谢@Pete的measureText函数: https://stackoverflow.com/a/4032497/442665 < / p >

你可能会对calc方法感兴趣:

font-size: calc(4vw + 4vh + 2vmin);

完成了。调整数值,直到符合你的口味。

来源:https://codepen.io/CrocoDillon/pen/fBJxu

这个解决方案也可能有帮助:

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

这对我很有效!

作为参考,一个非css解决方案:

下面是一些JS,根据容器内的文本长度来调整字体大小。

Codepen略有修改的代码,但相同的想法如下:

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;
}

所以,最终:

  • < p > 简短的文本:如。“苹果”

    完全渲染,漂亮的大字母。

  • < p > 长文本:如。“苹果,橘子”

    通过上面的JS缩放函数缩小70%

  • < p > 超长文本:如。“苹果,橙子,巴南区……”

    通过上面的JS缩放函数和CSS规则,缩小70%,并用“…”省略号截断

您还可以尝试使用CSS字母间距来使文本更窄,同时保持相同的字体大小。

尝试MartijnCuppens的RFS(响应式字体大小)库,可能会是在Bootstrap中实现

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

用这个方程。

对于大于或小于1440和768的任何值,您可以给它一个静态值,或者应用相同的方法。

vw解决方案的缺点是你不能设置缩放比例,比如在屏幕分辨率1440下的5vw最终可能是60px的字体大小,这是你的想法字体大小,但当你将窗口宽度缩小到768时,它可能最终是12px,而不是你想要的最小尺寸。使用这种方法,您可以设置上边界和下边界,字体将在两者之间自行缩放。

创建一个查找表,根据<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';
}

通过实证测试对所有参数进行调整和调优。

如果在引导4中从头开始

  1. https://bootstrap.build/app
  2. 单击搜索模式
  3. 搜索$enable-responsive-font-sizes并打开它。
  4. 单击“导出主题”保存自定义引导CSS文件。

我是这样使用smth的:

1.style。fontSize = 15.6/(document.getElementById("2").innerHTML.length)+ 'vw'

哪里:1 -父母div Id和2 - Id的div与我的文本

为什么不在服务器端根据字符数设置类呢?

    .NotMuchText {
font-size: 20px;
}


.LotsOfText {
font-size: 10px;
}

我还想要一个非javascript解决方案,CSS解决方案,并诉诸于PHP/CSS解决方案。

你的动态文本一定来自某个地方。在我的例子中,这看起来像:

<div class="large" :data-contentlength="Math.floor(item.name.length/7)">[[ item.name ]]</div>

我的CSS类:

.large[data-contentlength="1"]{ font-size: 1.2em; }
.large[data-contentlength="2"]{ font-size: 1.1em; }
.large[data-contentlength="3"]{ font-size: 1.0em; }
.large[data-contentlength="4"]{ font-size: 0.9em; }
.large[data-contentlength="5"]{ font-size: 0.8em; }
.large[data-contentlength="6"]{ font-size: 0.7em; }
.large[data-contentlength="7"]{ font-size: 0.6em; }

我也有“非大型”的课程。文本:

[data-length="1"]{ font-size: 1.00em; }
...
< p >编辑: 当attr()在所有浏览器中都可用时,这变得更容易一些: https://developer.mozilla.org/en-US/docs/Web/CSS/attr#browser_compatibility < / p >

此外,如果CSS可以划分2个单位值(例如px和ch),这可能会更动态,目前这必须手动完成。

在这里看到的:

https://jsfiddle.net/qns0pov2/3/

创建一个1ch的立方体,看看它在你的目标单位中有多大(在它的px中),计算每行字符的数量,并使用该值来获得每个内容长度的完美字体大小。

小提琴也显示了这种方法的问题:平均字符宽度小于1ch(基于0),但有像M这样的字符更大(大约70%)。

因此,如果你希望保证字符适合空格,调整小提琴如下:--ch-width: calc(8.109 * 1.7);

如果你对平均情况更感兴趣:--ch-width: calc(8.109 * 0.92);

我从BootStrap某处获得了这个动态字体大小calc(),并调整了它以适应。基于4pt系统和rem https://www.finsweet.com/client-first/docs/sizes的Webflow项目:

html {font-size: 16px;}

@import url('https://fonts.googleapis.com/css2?family=Poppins&display=swap');
body {font-family: 'Poppins', sans-serif;}


/*---SETUP BASE SIZE ---*/
html {font-size: 16px;}


/*---LINE-HEIGHTS + MARGINS---*/
[class^="display"], h1, h2, h3, h4 {
margin-top: 0;
margin-bottom: 1rem;
font-weight: 600;
}


.display-1, .display-2, .display-3, .display-4 {
line-height: 1.2;
    

}


h1, h2, h3, h4 {
line-height: 1.4;
}


p, ul, ol {
margin-bottom: 0.7rem;
line-height: 1.45;
}


.lead {
margin-bottom: 1rem;
line-height: 1.4;
}


/*---FONT SIZES 1279px DOWN---*/
@media (max-width: 1279px) {
.display-1 {
font-size: calc(1.625rem + 4.5vw);
}


.display-2 {
font-size: calc(1.575rem + 3.9vw);
}


.display-3 {
font-size: calc(1.525rem + 3.3vw);
}


.display-4 {
font-size: calc(1.475rem + 2.7vw);
}
  

/*---HEADINGS---*/
h1 {
font-size: calc(1.375rem + 1.5vw);
}


h2 {
font-size: calc(1.325rem + 0.9vw);
}


h3 {
font-size: calc(1.3rem + 0.6vw);
}


h4 {
font-size: calc(1.275rem + 0.3vw);
}


/*---PARAGRAPHS/UL/OL---*/
p, ul, ol  {
font-size: calc(0.823rem + 0.3vw);
}


.lead {
font-size: calc(1.01rem + 0.3vw);
}
}


/*---FONT SIZES ABOVE 1279px---*/
@media screen and (min-width: 1280px) {
.display-1 {
font-size: 5.22rem;
}


.display-2 {
font-size: 4.7rem;
}


.display-3 {
font-size: 4.16rem;
}


.display-4 {
font-size: 3.63rem;
}
/*---HEADINGS---*/
h1 {
font-size: 2.58rem;
}


h2 {
font-size: 2.05rem;
}


h3 {
font-size: 1.78rem;
}


h4 {
font-size: 1.52rem;
}


p, ul, ol {
font-size: 1.0625rem;
}


.lead {
font-size: 1.25rem;
}
}
<section>
<div class="container">
<p style="color:#8C8C8C;"><i>Note: Resize window too see text grow/shrink in browser window <= 1279px</i></p>
<br>
<h1 class="display-1">Display 1</h1>
<h1 class="display-2">Display 2</h1>
<h1 class="display-3">Display 3</h1>
<h1 class="display-4">Display 4</h1>
<br>
<br>
<br>
<br>
<h1>h1. The quick brown fox jumps over the lazy dog</h1>
<h2>h2. The quick brown fox jumps over the lazy dog</h2>
<h3>h3. The quick brown fox jumps over the lazy dog</h3>
<h4>h4. The quick brown fox jumps over the lazy dog</h4>
<p>The earliest known appearance of the phrase was in The Boston Journal. In an article titled "Current Notes" in the February 9, 1885, edition, the phrase is mentioned as a good practice sentence for writing students: "A favorite copy set by writing teachers for their pupils is the following, because it contains every letter of the alphabet: 'A quick brown fox jumps over the lazy dog.'"[2] Dozens of other newspapers published the phrase over the next few months, all using the version of the sentence starting with "A" rather than "The"</p>
<p>The earliest known use of the phrase starting with "The" is from the 1888 book Illustrative Shorthand by Linda Bronson.[4] The modern form (starting with "The") became more common even though it is slightly longer than the original (starting with "A").</p>
<p>A 1908 edition of the Los Angeles Herald Sunday Magazine records that when the New York Herald was equipping an office with typewriters "a few years ago", staff found that the common practice sentence of "now is the time for all good men to come to the aid of the party" did not familiarize typists with the entire alphabet, and ran onto two lines in a newspaper column. They write that a staff member named Arthur F. Curtis invented the "quick brown fox" pangram to address this.</p>
<br>
<br>
<br>
<br>
<p class="lead">Lead paragraph: As the use of typewriters grew in the late 19th century.</p>
<p>The phrase began appearing in typing lesson books as a practice sentence. Early examples include How to Become Expert in Typewriting: A Complete Instructor Designed Especially for the Remington Typewriter (1890),[6] and Typewriting Instructor and Stenographer's Hand-book (1892). By the turn of the 20th century, the phrase had become widely known. In the January 10, 1903, issue of Pitman's Phonetic Journal, it is referred to as "the well known memorized typing line embracing all the letters of the alphabet".</p>
<p>Robert Baden-Powell's book Scouting for Boys (1908) uses the phrase as a practice sentence for signaling.</p>
<p>The first message sent on the Moscow–Washington hotline on August 30, 1963, was the test phrase "THE QUICK BROWN FOX JUMPED OVER THE LAZY DOG'S BACK 1234567890".</p>
<br>
<br>
<br>
<br>
<ul class="list-unordered">
<li>During the 20th century, technicians tested typewriters and teleprinters by typing the sentence.</li>
<li>During the 20th century, technicians tested typewriters and teleprinters by typing the sentence.</li>
<li>During the 20th century, technicians tested typewriters and teleprinters by typing the sentence.</li>
<li>During the 20th century, technicians tested typewriters and teleprinters by typing the sentence.</li>
<li>During the 20th century, technicians tested typewriters and teleprinters by typing the sentence.</li>
<li>During the 20th century, technicians tested typewriters and teleprinters by typing the sentence.</li>
<li>During the 20th century, technicians tested typewriters and teleprinters by typing the sentence.</li>
</ul>
<br>
<br>
<br>
<br>
<ol class="list-ordered">
<li>During the 20th century, technicians tested typewriters and teleprinters by typing the sentence.</li>
<li>During the 20th century, technicians tested typewriters and teleprinters by typing the sentence.</li>
<li>During the 20th century, technicians tested typewriters and teleprinters by typing the sentence.</li>
<li>During the 20th century, technicians tested typewriters and teleprinters by typing the sentence.</li>
<li>During the 20th century, technicians tested typewriters and teleprinters by typing the sentence.</li>
<li>During the 20th century, technicians tested typewriters and teleprinters by typing the sentence.</li>
<li>During the 20th century, technicians tested typewriters and teleprinters by typing the sentence.</li>
</ol>
<br>
<br>
<br>
<br>
</div>
</section>

享受

由于接受的答案并不能真正解决问题,我在React中基于jkrei0的回答创建了一个解决方案。这将使动态文本根据其长度增长/收缩,就像在PowerPoint中一样。

下面是代码和框的链接:https://codesandbox.io/s/relaxed-rosalind-ielb8o