什么是 Scss 的等价物emCalc()
?
padding: emCalc(24px);
在 Scss 中将根据视点和缩放级别计算 em。less里面有内置函数吗?
您可以这样做将 px 转换为 em。
@font-size: 16; // Your base font-size in pixels
@em: @font-size*1em; // Shorthand for outputting ems, e.g. "12/@em"
@rem: @font-size*1rem; // Shorthand for outputting ems, e.g. "12/@rem"
h1{
font-size: 20/@em;
}
使用 LESS,您可以构建自己的功能。我将此功能与 grunt-contrib-less 包一起使用。格式与通常的较少函数格式略有不同。请注意,您需要在此包中插入 less 作为参数。
em: function(less, fontsize, basefontsize){
if (less.functions.functionRegistry.get('ispixel')){
basefontsize = (basefontsize) ? basefontsize.value : 16
return fontsize.value/basefontsize+'em';
}
}
现在你可以在你的 LESS 样式表中调用这个函数
.class{
font-size:em(16px);
}
这将编译为
.class{
font-size:1em;
}
注意 ems 仍然与容器的 css 相关。因此,例如,如果包装 div 的字体大小设置为 0.8em,则 1em 的字体大小将不是 16px。
更新:非 grunt-contrib-less 版本
如果你把它放在一个 javascript 文件中,该文件在你的 less 文件之前包含在你的 html 中,你可以使用上述函数。
$.extend(less.functions, {
em: function(fontsize, basefontsize){
if (this.ispixel(fontsize)){
basefontsize = (basefontsize) ? basefontsize.value : 16
return new(tree.Dimension)(fontsize.value/basefontsize,'em');
}
}
}
如果你在服务器端编译你的LESS,我个人永远不会这样做,否则你可以用LESS mixins而不是自定义函数来做到这一点。
这当然意味着你不能根据当前节点的大小自动计算,但这对我来说听起来有点吓人。这是将像素转换为 em 的另一种方法。
@emInPx: 16; // 16px per em (global default)
.convertEm(@selector, @amt) when (isem(@amt))
{
@{selector}: @amt;
}
.convertEm(@selector, @amt, @emInPx: @emInPx) when (ispixel(@amt))
{
@{selector}: unit((@amt / @emInPx), em);
}
img.cat
{
.convertEm(max-width, 5em);
.convertEm(max-height, 3em);
}
img.dog
{
.convertEm(max-width, 100px);
.convertEm(max-height, 75px);
}
请注意,我.convertEm(..)
对像素和 em 使用相同的 mixin,因为您甚至可能不知道该值是否作为参数传递。受保护的 mixin 正确地选择了正确的公式进行转换。
这会生成这个 css
img.cat {
max-width: 5em;
max-height: 3em;
}
img.dog {
max-width: 6.25em;
max-height: 4.6875em;
}
这一切都假设 1em 对应于 16px。如果不是,您可以根据您所在的上下文更改默认值或将其传入:
img.mouse
{
.convertEm(max-width, 100px, 32px);
.convertEm(max-height, 75px, 32px);
}
免责声明:我仍然不完全理解服务器生成的 LESS 如何或是否可以与自定义 javascript 函数一起使用,所以我假设当您生成服务器端时,您不能添加自定义函数。如果我错了,请有人告诉我!
根据文档,LESS 没有这样的功能。
请注意,Scss 对此函数的实现假定使用一个全局字体大小值进行转换。您可以使用变量轻松地在 LESS 中实现相同的目标:
@em: 16px; // LESS variable - default value for 1em
然后像这样使用它:
div {
height: @em;
width: 6 * @em;
}
上面的代码编译为:
div {
height: 16px;
width: 96px;
}
请注意,这(以及 Scss 的版本)不是真正的 em 工作方式,因为在 CSS 中指定的尺寸em
是根据使用它们的元素的字体大小计算的。
如果您在服务器端编译 LESS,您可以使用CSSHub
/* Test unit convert */
div {
.unit-convert(font, ~'bold em(14px)/1.2 @{csshub_font-stack-arial}');
// Ignore base: @csshub_font-size: 100%;
.unit-convert(margin, ~'rem(18px) rem(20px) rem(15px)', true);
// Default: 100% == 16px == 1em == 12pt == 1rem
.unit-convert(font-size, ~'px(100%)'); // Test: % to px
.unit-convert(font-size, ~'pt(16px)'); // Test: px to pt
.unit-convert(font-size, ~'em(12pt)'); // Test: pt to em
.unit-convert(font-size, ~'rem(1em)'); // Test: em to rem
.unit-convert(font-size, ~'percent(1rem)'); // Test: rem to %
}
这会生成这个 css
/* Test unit convert */
div {
font: bold 0.875em/1.2 Arial, 'Helvetica Neue', Helvetica, sans-serif;
margin: 1.125rem 1.25rem 0.9375rem;
font-size: 16px;
font-size: 12pt;
font-size: 1em;
font-size: 1rem;
font-size: 100%;
}
上面的例子都不适合我,所以我最终改变了它并且它有效:
@basefontsize: 14px;
.em(@fontsize, @basefontsize: @basefontsize) {
@result: if(ispixel(@fontsize), unit(unit(@fontsize)/unit(@basefontsize), em),@fontsize)
}
.my-class {
font-size: .em(16px)[];
padding-bottom: .em(14px)[];
padding-top: .em(14px, 16px)[];
margin-top: .em(32px)[];
margin-left: .em(2em)[];
margin-bottom: .em(4rem)[];
}
结果是:
.my-class {
font-size: 1.14285714em;
padding-bottom: 1em;
padding-top: 0.875em;
margin-top: 2.28571429em;
margin-left: 2em;
margin-bottom: 4rem;
}
此处显示了另一种变体。
/*
Toolkit: Rem
============
.rem() takes a @property, and @list of values (in px or unitless) and
converts to rem.
e.g.,
.selector {
.rem( margin, 20 auto eggs 666% );
.rem( font-size, 12 );
}
Makes life a little easier when working from designs specced in pixels.
*/
.rem( @property, @list, @base: 16 ) {
@n: length(@list);
// Only convert numbers that are not percentages or 0;
._merge( @px ) when ( isnumber(@px) ) and not ( ispercentage(@px) ) and not ( @px = 0 ) {
@rem: ( @px / @base );
@{property}+_: unit(@rem, rem);
}
._merge( @px ) when ( default() ) {
@{property}+_: @px;
}
._loop( @n ) when ( @n > 0 ) {
._loop((@n - 1));
@val: extract(@list, @n);
._merge( @val ); // merges values onto @property with space character.
}
._loop( @n );
}
资料来源:https ://gist.github.com/dominicwhittle/66275e9014bec7ec1b6f