如何获得calc()函数的无单位结果



我正在使用此计算来获得网页中的流体线高度:

line-height: calc(1.42em + (1.55 - 1.42) * ((100vw - 300px) / (1080 - 300)));

数学是有效的,除非我改变特定部分的font-size(因为line-height应该用一个无单位数来表示,以保持font-size/line-height的比率)。

问题是:如何从这个计算中得到无单位的结果?

我试过移除empx单元,但这破坏了效果。

如果我不使用这个计算,我可能会使用以下内容:

body {
font-size: 18px;
line-height: 1.4;
}

例如,我可以让calc()函数返回18px。但是,当我在calc()函数中使用其他多个单位时,如何让它返回一个无单位的结果(如:1.4)。有什么方法可以将结果转换为无单位的数字吗?


这是整个CSS:

:root {
--font: calc(16.2px + (18 - 16.2) * ((100vw - 300px) / (1080 - 300)));
--verti: calc(1.42em + (1.55 - 1.42) * ((100vw - 300px) / (1080 - 300)));
}
html {
font-family: "Georgia";
font-size: var(--font);
line-height: var(--verti);
}
.small {
font-size: 0.8em;
}

这工作很棒。但是,类.smallline-height太大了。我可以为它做另一个calc()函数,也可以让预览calc()用一个无单位数返回它的值。

如果您的任何输入都有单位,则不可能从calc()中获得无单位值。

然而,特别是在line-height的这种特殊情况下,应该注意的是,line-height: 1.4的无单位值等于line-height: 140%。同样,3.1等效于310%等。您应该能够修改calc()方程,以使用%单位输出所需值。


编辑:对于无单位值和百分比值,继承的表现似乎不同,所以要谨慎使用这种方法。如果避免在父元素上指定line-height,则应该可以。https://developer.mozilla.org/en-US/docs/Web/CSS/line-height#Prefer_unitless_numbers_for_line-高度值

到目前为止,还没有CSS方法从使用单位的calc(..)的结果中剥离单位。该解决方案将向您展示一种根据需要获得主CCD_ 23和CCD_,以及CCD_ 25类的那些。使用单位时。。。

tl;dr=>代码段

window.onload = window.onresize  = function() { showInfo() }
/*
Get current a11y slider value and assign to custom variable.
*/
// References to page slider elements
const slider = document.getElementById('slider'); // a11y slider
const a11y   = document.getElementById('a11y');   // a11y slider value info
const sliderSetScale = () => {
// Show current slider value
a11y.innerHTML = slider.value;

// Assign to CSS custom variable
document.documentElement.style.setProperty('--a11y-scale', slider.value);
// Show updated size values
showInfo();
}
/*
Show current font-size and line-height of demo elements.
*/
// References to page info elements
const nI     = document.getElementById('nInfo');  // normal info
const sI     = document.getElementById('sInfo');  // small info
const showInfo = () => {
// Show current slider value
a11y.innerHTML = slider.value;
// Get current style values
let nIst = getComputedStyle(nI);
let sIst = getComputedStyle(sI);
// Display current values (macro using 'backticks')
nI.innerHTML = `fs: ${nIst.fontSize}, lh: ${nIst.lineHeight}`;
sI.innerHTML = `fs: ${sIst.fontSize}, lh: ${sIst.lineHeight}`;
}
:root {
/* generic multiplier for a11y scaling of page elements */
--a11y-scale: 1;
/*
Linear Equation y = mx + b
point slope form: y − y1 = m(x − x1) 
substituted: y = y1 + (y2 − y1) / (x2 − x1) × (x − x1)

using points p1(x1,y1) and p2(x2,y2):
font-size   => p1(300, 16.2)        p2(1080, 18)
line-height => p1(300, 16.2 * 1.42) p2(1080, 18 * 1.55)

multiply endresult (y) with generic multiplier for element scaling
*/
/* Filling in the above equation (2x use of 'px' otherwise the calc will fail) */
--fs: calc( (16.2px        + (18.0 - 16.2)             / (1080 - 300) * (100vw - 300px)) * var(--a11y-scale) );
--lh: calc( (16.2px * 1.42 + (18 * 1.55 - 16.2 * 1.42) / (1080 - 300) * (100vw - 300px)) * var(--a11y-scale) );
/* NOTE: not simplified for demo purposes */
}
body {
font-size  : var(--fs);
line-height: var(--lh);
}
.normal {
font-size: 1rem;
line-height: normal;
}
.small {
font-size  : calc(0.8 * var(--fs));
line-height: calc(0.8 * var(--lh));
}
.box {
/* for easy centering of text */
display: grid; place-items: center;
/* create a responsive square using 'em' unit    */
width : 6em; height: 6em; /* font size depending */
/* main font size is a11y scaled, so is the box  */
background-color: Gainsboro;
}
/* just eye-candy */
.wwrapper * { outline: 1px dashed }
input[type="range"] { width: 100% }
/*
-----------------------------------------
Linear Equation y=mx+b math in a Nutshell
-----------------------------------------
Using points p1(x1,y1) and p2(x2,y2) where
x1,y1 = the small viewport size (x1) where required small size is (y1)
x2,y2 = the large viewport size (x2) where required large size is (y2)
NOTE: the above will yield a rising slope, while using
(y1) = large and (y2) = small will yield a falling slope,
basically creating the inverse effect.
on a 2D graph with
x-axis = viewport size values
y-axis = size attribute values
and variable definitions
y = the calculated size we want to use in CSS
m = (y2 − y1) / (x2 − x1) => delta Y / delta X => the 'change'
x = either 100vh, vw, vmin or vmax, determined by viewport width/height dependency
b = y1 − m × x1 => value of y when x = 0
we use the equation 'point slope form'
equation: y − y1 = m(x − x1)
substituted: y = y1unit + (y2 − y1) / (x2 − x1) × (x − x1unit)
NOTE: in calc(..) attach a unit to the values where depicted
or multiply with 1unit when using variables, otherwise
the calc(..) will fail.
to calculate any CSS size property value that has to responsively
and fluidly scale relative to the current viewport width or height.
*/
<!-- https://stackoverflow.com/questions/60895353/how-to-get-a-unit-less-result-of-the-calc-function -->
<label>a11y scale <span id="a11y"></span>
<input id="slider" type="range" min="0.5" max="3" step="0.01" value="1"
oninput="sliderSetScale()">
</label>
<div class="wrapper">
<div class="normal">this is unresponsive text for reference</div>
<div>this is responsive text                      (<span id="nInfo"></span>)</div>
<div class="small" >this is small responsive text (<span id="sInfo"></span>)</div>
<br>
<div class="box">box</div>
</div>

记住

  • 您使用的是线性方程y=mx+b的"点斜率形式"直线上两点的坐标:p1(x1,y1)p2(x2,y2)calc(..)中使用的替代方程:y=y1+(y2−y1)/(x2−x1)×(x−x1)
  • 无单位line-height是[可选],接受任何合法单位
  • "em"单位是取决于元件电流font-size的乘法器
  • 无单位line-height是与'em'单位相当的乘数,但font-size无关
  • OPline-height取决于视口,只有似乎取决于父font-size
  • .small line-height不能将em用于line-height,因为它不是计算的

从OPcalc(..)方程导出的约束

  • ,视口宽度为300px:主font-size: 16.2pxline-height: 1.42em
  • 视口宽度为1080px时:主font-size: 18pxline-height: 1.55em
  • .small需要是主font-sizeline-height0.8em

将约束转化为方程,去掉em单元(因为它只是一个乘法器):

  1. font-size=>点p1(300,16.2)p2(1080,18)
  • 在300px的视口宽度下,它应该是16.2px

  • 在1080px的视口宽度下,它应该是18px

  • 公式:--fs: calc(16.2px + (18.0 - 16.2) / (1080 - 300) * (100vw - 300px))

  1. line-height=>点p1(300,16.2*1.42)p2(1080,18*1.55)
  • 在300px的视口宽度下,它应该是16.2px * 1.42

  • 在1080px的视口宽度下,它应该是18px * 1.55

  • 公式--lh: calc(16.2px * 1.42 + (18 * 1.55 - 16.2 * 1.42) / (1080 - 300) * (100vw - 300px))

由于我们现在有了基本值,我们可以使用这些值来定义元素所需的所有字体大小和行高。

例如对于.small,我们现在可以使用font-size: calc(0.8 * var(--fs))line-height: calc(0.8 * var(--fs)),因为父字体大小--fs母行高度--lh

缺点使用此方法,当我们需要计算响应大小时,我们不能再使用em单元。使用em的简单font-size依赖关系仍然是可能的(请参阅代码片段中的.box)。

奖金

我在上面的片段中介绍了自定义变量--a11y-scale,展示了如何使用通用元素乘数来缩放元素以实现可访问性。它只是将方程的结果与range slider值相乘。基本上显示了如何组合计算手动缩放。

在CSS的剩余部分中,您可以找到线性数学的摘要。

最新更新