Fra*_*sca 1083 css font-size responsive-design
我很难理解字体缩放.
我目前有这个网站的身体font-size100%.但是100%的是什么?这似乎计算在16px.
我的印象是,100%会以某种方式引用浏览器窗口的大小,但显然不是因为它总是16px,无论窗口是否调整为移动宽度或完整的宽屏桌面.
如何使我的网站上的文本与其容器相关?我尝试过使用,em但这也没有扩展.
我的理由是,事情就像我的菜单中就当调整压扁,所以我需要减少PX px的font-size相对其它元素的容器的宽度之中.(例如,在大型桌面上的菜单中,22px可以完美运行.向下移动到平板电脑宽度,16px更合适.)
我知道我可以添加断点,但我真的希望文本可以扩展为具有额外的断点,否则我将最终为每100px宽度减少数百个断点来控制文本.
jbe*_*son 1405
编辑:如果容器不是主体 CSS Tricks涵盖了您的所有选项:https://css-tricks.com/fitting-text-to-a-container/
如果容器是正文,那么您要查找的是视口百分比长度:
该视口百分比长度是相对于的大小包含初始块.当初始包含块的高度或宽度改变时,它们相应地缩放.但是,当根元素上的溢出值为auto时,假定不存在任何滚动条.
价值观是:
vw (视口宽度的百分比)vh (视口高度的百分比)vi (在根元素的内联轴方向上视口大小的1%)vb (根元素块轴方向上视口大小的1%)vmin(较小的vw或vh)vmax(较大的或vw或vh)1 v*等于初始包含块的1%.
使用它看起来像这样:
p {
font-size: 4vw;
}
Run Code Online (Sandbox Code Playgroud)
如您所见,当视口宽度增加时,font-size也会增加,而无需使用媒体查询.
这些值是一个大小单位,就像px或em,因此它们也可用于调整其他元素的大小,例如宽度,边距或填充.
浏览器支持非常好,但您可能需要回退,例如:
p {
font-size: 16px;
font-size: 4vw;
}
Run Code Online (Sandbox Code Playgroud)
查看支持统计信息:http://caniuse.com/#feat=viewport-units.
另外,请查看CSS-Tricks以获得更广泛的外观:http://css-tricks.com/viewport-sized-typography/
这是一篇很好的文章,关于设置最小/最大尺寸并对尺寸进行更多控制:http://madebymike.com.au/writing/precise-control-responsive-typography/
这里有一篇关于使用calc()设置大小的文章,以便文本填充视口:http://codepen.io/CrocoDillon/pen/fBJxu
另外,请查看这篇文章,该文章使用了一种名为"熔化前导"的技术来调整线高.https://css-tricks.com/molten-leading-css/
Sco*_*ttS 305
Alex根据接受的答案在评论中提出了这个问题.
这个事实并不意味着vw在某种程度上不能用于该容器的大小.现在要看到任何变化都必须假设容器在某种程度上是灵活的.无论是通过直接百分比width还是通过100%减去利润率.如果容器总是被设置为200px宽,那么这个点变得"没有实际意义" - 那么只需设置一个font-size适用于该宽度的容器.
例1
然而,对于柔性宽度的容器,必须认识到,在某种程度上,容器仍然在视口外的尺寸.因此,需要vw根据与视口的百分比大小差异来调整设置,这意味着要考虑父包装的大小.举个例子:
div {
width: 50%;
border: 1px solid black;
margin: 20px;
font-size: 16px;
/* 100 = viewport width, as 1vw = 1/100th of that
So if the container is 50% of viewport (as here)
then factor that into how you want it to size.
Let's say you like 5vw if it were the whole width,
then for this container, size it at 2.5vw (5 * .5 [i.e. 50%])
*/
font-size: 2.5vw;
}
Run Code Online (Sandbox Code Playgroud)
这里假设div是的一个孩子body,这是50%那的100%宽度,这是在这个基本情况视口大小.基本上,你想要设置一个vw对你来说很好看的东西.正如您在上面的css中的评论中所看到的,您可以通过数学方式"思考"整个视口大小,但您不需要这样做.文本将与容器"flex",因为容器在视口大小调整时弯曲.更新:这是两个不同大小的容器的示例.
例2
您可以通过强制执行基于此计算的计算来帮助确保视口大小调整.考虑这个例子:
html {width: 100%;} /* Force 'html' to be viewport width */
body {width: 150%; } /* Overflow the body */
div {
width: 50%;
border: 1px solid black;
margin: 20px;
font-size: 16px;
/* 100 = viewport width, as 1vw = 1/100th of that
Here, the body is 150% of viewport, but the container is 50%
of viewport, so both parents factor into how you want it to size.
Let's say you like 5vw if it were the whole width,
then for this container, size it at 3.75vw
(5 * 1.5 [i.e. 150%]) * .5 [i.e. 50%]
*/
font-size: 3.75vw;
}
Run Code Online (Sandbox Code Playgroud)
大小调整仍然基于视口,但实质上是根据容器大小本身设置的.
如果容器元素的大小最终通过@media断点或通过javascript 动态地改变其百分比关系,则无论基础"目标"是什么,都需要重新计算以维持文本大小调整的相同"关系".
以上面的例子#1为例.如果通过javascript或javascript div切换到25%宽度@media,那么同时,font-size需要在媒体查询中调整或通过javascript调整到新的计算5vw * .25 = 1.25.这将使文本大小与原始50%容器的"宽度" 从视口大小减少一半时的大小相同,但现在由于其自身百分比计算的变化而减小.
一个挑战
使用CSS3 calc()功能时,动态调整将变得困难,因为此功能目前无法正常工作font-size.因此,如果您的宽度正在变化,则无法进行纯CSS3调整calc().当然,对边距宽度的微小调整可能不足以保证任何变化font-size,因此可能无关紧要.
Cas*_*mir 140
2022 年末添加的 CSS 功能集使使用容器缩放字体大小变得简单。
容器查询带有一组新的 CSS 单元/cqw(cqh容器查询宽度/ h八)。要使用它们,您需要在要使用其大小的父元素上设置属性(不必是直接父元素)。最小的例子:container-type
<div>
<p>Lorem ipsum dolor sit amet</p>
</div>
<style>
div {
container-type: inline-size;
}
p {
font-size: 5cqw;
}
</style>Run Code Online (Sandbox Code Playgroud)
字体大小会随着容器的增大而平滑增大。当容器宽度为 1000px 时,p字体大小将为1000px / 100 * 5 = 50px.
container-type可以是size或inline-size。size跟踪容器的高度和宽度,这允许您同时使用cqw和cqh。在网络上的大多数情况下,高度是根据内容计算的,您只需指定宽度。为了节省浏览器的一些工作,您通常需要进行设置container-type: inline-size;,以便浏览器仅跟踪内联尺寸,通常是宽度(除非您设置writing-mode为垂直)。
浏览器对容器查询的支持正在迅速增长:
Dan*_*tio 49
SVG解决方案:
<div style="width: 60px;">
<svg width="100%" height="100%" viewBox="0 -200 1000 300"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<text font-size="300" fill="black">Text</text>
</svg>
</div>
Run Code Online (Sandbox Code Playgroud)
https://jsfiddle.net/qc8ht5eb/
lsb*_*lsb 32
我在我的一个项目中做的是在vw和vh之间的"混合",以根据我的需要调整字体大小,例如:
font-size: calc(3vw + 3vh);
Run Code Online (Sandbox Code Playgroud)
我知道这不能回答op的问题,但也许它可以成为其他任何人的解决方案.
Dan*_*cut 26
这个问题有一个很大的哲学.最简单的做法是给身体一个字体大小(我推荐10),然后所有其他元素的字体都在em或rem中.我会举例说明这些单位.Em始终与父母相关
body{font-size: 10px;}
.menu{font-size: 2em;} /* That means 2*10 pixels = 20 pixels */
.menu li{font-size: 1.5em;} /* That means 1.5*20 pixels = 30 pixels */
Run Code Online (Sandbox Code Playgroud)
Rem始终与身体相关
body{font-size: 10px;}
.menu{font-size: 2rem;} /* That means 2*10 pixels = 20 pixels */
.menu li{font-size: 1.5rem;} /* that means 1.5*10 pixels = 15 pixels */
Run Code Online (Sandbox Code Playgroud)
而且你可以创建一个脚本来修改相对于容器宽度的字体大小.但这不是我想要的.因为在900px宽度的容器中,你可以说有一个em12px字体大小的元素.并且在你的ideea上将成为300px宽度容器,4px字体大小.必须有一个下限.另一种解决方案是使用媒体查询,以便您可以为不同的宽度设置字体.
但我建议的解决方案是使用一个javascript库来帮助你.而fittext.js我发现至今.
tnt*_*rox 23
更新,因为我投了一票.
这是功能:
document.body.setScaledFont = function(f) {
var s = this.offsetWidth, fs = s * f;
this.style.fontSize = fs + '%';
return this
};
Run Code Online (Sandbox Code Playgroud)
然后将所有文档子元素字体大小转换为em或%.
然后在代码中添加这样的内容以设置基本字体大小.
document.body.setScaledFont(0.35);
window.onresize = function() {
document.body.setScaledFont(0.35);
}
Run Code Online (Sandbox Code Playgroud)
heg*_*gez 22
calc(),CSS单位和数学这正是OP所要求的,但可能会成为某人的一天.这个答案并非易于使用,需要在开发人员端进行一些研究.
我终于得到了一个纯CSS的解决方案,使用calc()不同的单位.您需要对公式进行一些基本的数学理解才能计算出您的表达式calc().
当我解决这个问题时,我不得不得到一个整页宽度响应的标题,其中一些填充在DOM中的父母很少.我会在这里使用我的值,用你自己的值替换它们.
你会需要:
padding: 3em和全宽所以这就到了100wv - 2 * 3emX是容器的宽度,因此请使用您自己的表达式替换它,或者调整值以获取整页文本.R是你将拥有的比率.您可以通过调整某些视口中的值,检查元素宽度和高度并使用您自己的值替换它们来获取它.而且,它是R;)
x = 100vw - 2 * 3em = 100vw - 6em
r = 224px/24px = 9.333... = 28 / 3
y = x / r
= (100vw - 6em) / (28 / 3)
= (100vw - 6em) * 3 / 28
= (300vw - 18em) / 28
= (75vw - 4.5rem) / 7
Run Code Online (Sandbox Code Playgroud)
砰!有效!我写
font-size: calc((75vw - 4.5rem) / 7)
Run Code Online (Sandbox Code Playgroud)
到我的标题,它在每个视口中调整得很好.
我们需要一些常量.width / heigth表示视口的整个宽度,我的目标是使用一些填充建立全宽标题.
比例.在一个视口中获得宽度和高度让我得到一个比率,并且我知道在其他视口宽度中的高度应该是多少.用手计算它们需要花费大量的时间,至少需要大量的带宽,所以这不是一个好的答案.
我想知道为什么没有人想到这一点,有些人甚至说这不可能修补CSS.我不喜欢在调整元素时使用Javascript,所以我不接受JS甚至jQuery的答案而不需要挖掘更多.总而言之,这一点很好,这是网站设计中纯CSS实现的一步.
我为我的文本中的任何不寻常的约定道歉,我不是英语母语,也不是写SO答案的新手.
编辑:还应该注意我们在某些浏览器中有邪恶的滚动条.例如,当我使用Firefox时,我注意到这100vw意味着视口的整个宽度,在滚动条下扩展(内容无法展开!),因此全文文本必须仔细边缘化,最好通过许多浏览器和设备进行测试.
Aar*_*ten 18
有一种方法可以做到这一点没有javascript!
你可以使用内联svg.如果它是内联的,你可以在svg上使用css.您必须记住,使用此方法意味着您的svg将响应其容器大小.
尝试使用以下解决方案......
HTML
<div>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 360.96 358.98" >
<text>SAVE $500</text>
</svg>
</div>
Run Code Online (Sandbox Code Playgroud)
CSS
div {
width: 50%; /* Set your container width */
height: 50%; /* Set your container height */
}
svg {
width: 100%;
height: auto;
}
text {
transform: translate(40px, 202px);
font-size: 62px;
fill: #000;
}
Run Code Online (Sandbox Code Playgroud)
示例:https: //jsfiddle.net/k8L4xLLa/32/
想要更华丽的东西吗?
SVG还允许你做形状和垃圾的酷东西.查看这个可扩展文本的大用例...
https://jsfiddle.net/k8L4xLLa/14/
Rom*_*ler 14
这可能不是很实用,但是如果你想让font成为父类的直接函数,而没有任何JS监听/循环(interval)来读取div/page的大小,那么就有办法做到这一点.I帧.iframe中的任何内容都会将iframe的大小视为视口的大小.因此,诀窍是只创建一个iframe,其宽度是您希望文本的最大宽度,其高度等于特定文本的纵横比的最大高度*.
抛开视口单元不能同时出现文本的旁边父单元的限制(例如,%大小的行为与其他人一样),视口单元确实提供了一个非常强大的工具:能够获得最小/最大维度.你不能在其他任何地方做到这一点 - 你不能说..使这个div的高度成为父*的宽度.
话虽这么说,诀窍是使用vmin,并设置iframe大小,以便当高度是限制尺寸时,[fraction]*总高度是一个好的字体大小,当宽度是时,[fraction]*总宽度限制尺寸.这就是为什么高度必须是宽度和纵横比的乘积.
对于我的特例,你有
.main iframe{
position: absolute;
top: 50%;
left: 50%;
width: 100%;
height: calc(3.5 * 100%);
background: rgba(0, 0, 0, 0);
border-style: none;
transform: translate3d(-50%, -50%, 0);
}
Run Code Online (Sandbox Code Playgroud)
使用此方法的小麻烦是您必须手动设置iframe的CSS.如果附加整个CSS文件,则会占用许多文本区域的大量带宽.所以,我所做的是直接从我的CSS附加我想要的规则.
var rule = document.styleSheets[1].rules[4];
var iDoc = document.querySelector('iframe').contentDocument;
iDoc.styleSheets[0].insertRule(rule.cssText);
Run Code Online (Sandbox Code Playgroud)
您可以编写小函数来获取可能影响文本区域的CSS规则/所有CSS规则.
没有一些骑自行车/听取JS的话,我想不出另一种方法.真正的解决方案是浏览器提供一种方法来缩放文本作为父容器的函数,并提供相同的vmin/vmax类型功能.
JS小提琴:https: //jsfiddle.net/0jr7rrgm/3/ (单击一次将红色方块锁定到鼠标,再次单击以释放)
小提琴中的大部分JS都只是我的自定义点击拖动功能
使用vw,em&co.确实很有效,但我总是需要一个人的触摸来进行微调.
这是我刚刚根据@ tnt-rox' 回答写的一个脚本,试图自动化人类的触摸:
$('#controller').click(function(){
$('h2').each(function(){
var
$el = $(this),
max = $el.get(0),
el = null
;
max =
max
? max.offsetWidth
: 320
;
$el.css({
'font-size': '1em',
'display': 'inline',
});
el = $el.get(0);
el.get_float = function(){
var
fs = 0
;
if (this.style && this.style.fontSize) {
fs = parseFloat(this.style.fontSize.replace(/([\d\.]+)em/g, '$1'));
}
return fs;
};
el.bigger = function(){
this.style.fontSize = (this.get_float() + 0.1) + 'em';
};
while (el.offsetWidth < max) {
el.bigger();
}
// Finishing touch.
$el.css({
'font-size': ((el.get_float() -0.1) +'em'),
'line-height': 'normal',
'display': '',
});
}); // end of (each)
}); // end of (font scaling test)Run Code Online (Sandbox Code Playgroud)
div {
width: 50%;
background-color: tomato;
font-family: 'Arial';
}
h2 {
white-space: nowrap;
}
h2:nth-child(2) {
font-style: italic;
}Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input type="button" id="controller" value="Apply" />
<div>
<h2>Lorem ipsum dolor</h2>
<h2>Test String</h2>
<h2>Sweet Concatenation</h2>
<h2>Font Scaling</h2>
</div>Run Code Online (Sandbox Code Playgroud)
它基本上将字体大小减小到1em然后开始递增0.1,直到达到最大宽度.
我自己的解决方案,基于jQuery,通过逐渐增加字体大小,直到容器的高度大幅增加(意味着它有一个换行符).它很简单,但工作得很好,而且非常容易使用.您不必了解所使用的字体,浏览器会处理所有内容.
你可以在http://jsfiddle.net/tubededentifrice/u5y15d0L/2/上玩它
魔术发生在这里:
var setMaxTextSize=function(jElement) {
// Get and set the font size into data for reuse upon resize
var fontSize=parseInt(jElement.data(quickFitFontSizeData)) || parseInt(jElement.css("font-size"));
jElement.data(quickFitFontSizeData, fontSize);
// Gradually increase font size until the element gets a big increase in height (i.e. line break)
var i = 0;
var previousHeight;
do
{
previousHeight=jElement.height();
jElement.css("font-size", "" + (++fontSize) + "px");
}
while(i++ < 300 && jElement.height()-previousHeight < fontSize/2)
// Finally, go back before the increase in height and set the element as resized by adding quickFitSetClass
fontSize -= 1;
jElement.addClass(quickFitSetClass).css("font-size", "" + fontSize + "px");
return fontSize;
};
Run Code Online (Sandbox Code Playgroud)
小智 7
还没有人提到 CSS 变量,这种方法最适合我,所以:
假设您的页面上有一列的宽度为移动用户屏幕宽度的 100%,但 amax-width为 800px,因此在桌面上,该列的两侧都有一些空间。将其放在页面顶部:
<script> document.documentElement.style.setProperty('--column-width', Math.min(window.innerWidth, 800)+'px'); </script>
Run Code Online (Sandbox Code Playgroud)
现在您可以使用该变量(而不是内置vw单位)来设置字体的大小。例如
p {
font-size: calc( var(--column-width) / 100 );
}
Run Code Online (Sandbox Code Playgroud)
这不是纯CSS 方法,但非常接近。
从艺术上讲,如果您需要在相同宽度内放置两行或更多行文本,而不管它们的字符数如何,那么您有不错的选择。
最好找到一个动态解决方案,这样无论输入什么文本,我们最终都会得到一个很好的显示。
让我们看看我们可以如何处理。
var els = document.querySelectorAll(".divtext"),
refWidth = els[0].clientWidth,
refFontSize = parseFloat(window.getComputedStyle(els[0],null)
.getPropertyValue("font-size"));
els.forEach((el,i) => el.style.fontSize = refFontSize * refWidth / els[i].clientWidth + "px")Run Code Online (Sandbox Code Playgroud)
#container {
display: inline-block;
background-color: black;
padding: 0.6vw 1.2vw;
}
.divtext {
display: table;
color: white;
font-family: impact;
font-size: 4.5vw;
}Run Code Online (Sandbox Code Playgroud)
<div id="container">
<div class="divtext">THIS IS JUST AN</div>
<div class="divtext">EXAMPLE</div>
<div class="divtext">TO SHOW YOU WHAT</div>
<div class="divtext">YOU WANT</div>
</div>Run Code Online (Sandbox Code Playgroud)
我们所做的只是获取第一行的宽度(els[0].clientWidth)和字体大小(parseFloat(window.getComputedStyle(els[0],null).getPropertyValue("font-size")))作为参考,然后相应地计算后续行的字体大小。
小智 6
在你的CSS内部尝试在底部添加这个更改320px宽度,无论你的设计开始破坏:
@media only screen and (max-width: 320px) {
body { font-size: 1em; }
}
Run Code Online (Sandbox Code Playgroud)
然后根据需要在"px"或"em"中给出font-size.
你在找这样的东西吗?=>
http://jsfiddle.net/sijav/dGsC9/4/
http://fiddle.jshell.net/sijav/dGsC9/4/show/
我使用了flowtype并且工作得很好(不过它是js而不是纯css解)
$('body').flowtype({
minFont: 10,
maxFont: 40,
minimum: 500,
maximum: 1200,
fontRatio: 70
});
Run Code Online (Sandbox Code Playgroud)
此Web组件更改字体大小,以使内部文本宽度与容器宽度匹配.检查演示.
你可以像这样使用它:
<full-width-text>Lorem Ipsum</full-width-text>
Run Code Online (Sandbox Code Playgroud)
小智 6
我已经使用css变换而不是font-size准备了简单的缩放函数.你可以在任何容器内使用它,你不必设置媒体查询等:)
博客文章:https: //blog.polarbits.co/2017/03/07/full-width-css-js-scalable-header/
代码:
function scaleHeader() {
var scalable = document.querySelectorAll('.scale--js');
var margin = 10;
for (var i = 0; i < scalable.length; i++) {
var scalableContainer = scalable[i].parentNode;
scalable[i].style.transform = 'scale(1)';
var scalableContainerWidth = scalableContainer.offsetWidth - margin;
var scalableWidth = scalable[i].offsetWidth;
scalable[i].style.transform = 'scale(' + scalableContainerWidth / scalableWidth + ')';
scalableContainer.style.height = scalable[i].getBoundingClientRect().height + 'px';
}
}
Run Code Online (Sandbox Code Playgroud)
工作演示:https: //codepen.io/maciejkorsan/pen/BWLryj
我的问题很相似,但与标题中的缩放文本有关.我尝试了Fit Font,但我需要切换压缩器以获得任何结果,因为它解决了一个稍微不同的问题,就像Text Flow一样.所以我写了我自己的小插件,减少了字体大小以适应容器,假设你有overflow: hidden,white-space: nowrap所以,即使将字体减少到最小不允许显示完整的标题,它只是切断它可以显示的东西.
(function($) {
// Reduces the size of text in the element to fit the parent.
$.fn.reduceTextSize = function(options) {
options = $.extend({
minFontSize: 10
}, options);
function checkWidth(em) {
var $em = $(em);
var oldPosition = $em.css('position');
$em.css('position', 'absolute');
var width = $em.width();
$em.css('position', oldPosition);
return width;
}
return this.each(function(){
var $this = $(this);
var $parent = $this.parent();
var prevFontSize;
while (checkWidth($this) > $parent.width()) {
var currentFontSize = parseInt($this.css('font-size').replace('px', ''));
// Stop looping if min font size reached, or font size did not change last iteration.
if (isNaN(currentFontSize) || currentFontSize <= options.minFontSize ||
prevFontSize && prevFontSize == currentFontSize) {
break;
}
prevFontSize = currentFontSize;
$this.css('font-size', (currentFontSize - 1) + 'px');
}
});
};
})(jQuery);
Run Code Online (Sandbox Code Playgroud)
这是一个纯 CSS 解决方案,您承认断点是必要的,但也希望文本缩放:
我知道我可以添加断点,但我真的希望文本能够缩放并具有额外的断点,否则......
这是一种使用以下方法的方法:
clamp()(2022 年 2 月的浏览器支持率非常好,达到 93%)calc()如果可以使用一个通用缩放因子来控制每个屏幕容器内的所有max-width文本缩放,那么您所需要做的就是缩放每个自定义属性max-width,并将该因子应用于 1 次计算。
基本设置如下所示:
:root {
--scaling-factor: 1
}
.parent {
font-size: 30px
}
.largest {
font-size: clamp(60%, calc(var(--scaling-factor) * 100%), 100%);
}
.middle {
font-size: clamp(60%, calc(var(--scaling-factor) * 85%), 100%);
}
.smallest {
font-size: clamp(60%, calc(var(--scaling-factor) * 70%), 100%);
}
Run Code Online (Sandbox Code Playgroud)
然后嵌套您的媒体查询,如下所示(或您的断点所需的任何内容):
@media (max-width: 1200px) {
:root {
--scaling-factor: 0.9
}
@media (max-width: 800px) {
:root {
--scaling-factor: 0.8
}
@media (max-width: 600px) {
:root {
--scaling-factor: 0.5 /* nope, because the font-size is floored at 60% thanks to clamp() */
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
这可以最大限度地减少媒体查询标记。
优点
clamp()设置了 的下限font-size,因此可以确保文本永远不会太小(这里的下限是父级的 60% font-size)请参阅此 JSFiddle的演示。调整窗口大小,直到在最小宽度下,段落全部相同font-size。