”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > CSS与Sass精度的故事

CSS与Sass精度的故事

发布于2025-05-03
浏览:834

百分比布局的挑战:浏览器差异和浮点精度问题

百分比布局因浏览器不一致性和浮点精度缺乏规范而极具挑战性,这可能导致渲染对齐和精度问题。

Sass 的优势:提升精度和代码可读性

Sass 作为一种预处理器脚本语言,可以通过处理复杂的计算来提高精度,并使样式表更易于阅读和更新。然而,Sass 的默认精度选项为 5,对于某些情况来说可能仍然太低。

calc() 函数:浏览器计算和舍入

calc(..) CSS 函数允许浏览器处理计算和舍入,可能产生更好的结果。此函数与 Sass 运算相结合,可以为 CSS 精度提供两全其美的方案。

A Tale of CSS and Sass Precision

在 Edenspiekermann,我们依赖代码审查来确保我们提交的工作足够好™。我经常遇到的一件事是围绕数字(尤其是带有小数点的数字)的模糊性。因此,这是一篇简短的文章,旨在阐明这个问题。

初始设置

为了在开始之前使整个解释更清晰,我们将处理一小段代码,这与我们的案例非常相关。

.list-item {
  float: left;
  width: 33%;
}

问题是什么?

您可能想知道这段代码有什么问题。从外观上看,问题不大。这是一个三列网格布局,相当常见。

但是,33% 33% 33% 等于 99%,而不是 100%。虽然在大多数情况下这可能没有任何区别,但在处理直线对齐时——1% 会产生很大影响。1400 像素宽的容器的 1% 是 14 像素。这是一个相当大的距离。

为什么我们不能只移动小数点(或者添加它)以使其更精确呢?我们可能会将间隙减少到 1.4 像素,甚至 0.14 像素,我想这已经不值得费心了!那就从这里开始吧。

.list-item {
  float: left;
  width: 33.33%;
}

效果更好,但仍然不完美。John Albin Wilkins 在题为“响应式设计的肮脏小秘密”的这篇文章中对这个问题进行了广泛的讨论。如果您还没有阅读它,请阅读它。

浏览器不能处理这个问题吗?

此时,您可能想知道为什么浏览器不能让它工作™。问题是,CSS 规范没有(具有讽刺意味的是)向浏览器厂商指定在百分比数字的浮点精度情况下该怎么做。当 CSS 规范省略细节时,您可以确定每个浏览器都会以自己的方式处理它。

以下来自上述文章的示例:

[…] 使用 6 列网格,每列宽度为 100% ÷ 6 = 16.666667%。在 1000 像素宽的视口中(我方便地选择它以使我们的数学更容易),每列计算为 166.66667 像素。由于规范没有给出指导方针,浏览器厂商可以自由制定自己的规则。如果浏览器四舍五入到最接近的像素,在我们的示例中,我们将得到 167 像素。但由于 167 x 6 = 1002 像素,我们不再有空间在我们的视口中容纳所有 6 列。或者,如果浏览器向下舍入到每列 166 像素,我们将比完美地将所有列放入我们的视口中少 4 像素。——John Albin Wilkins

这就是发生的事情。旧版本的 Internet Explorer(主要是 6 和 7)四舍五入到最接近的整数,导致布局中断。WebKit 浏览器向下舍入,这可以防止任何灾难性的布局结果,但会给我们留下额外的空间。Opera(至少在其旧的渲染引擎中)做了一些我甚至懒得解释的奇怪事情。但是,规范中没有关于此行为的规则,那么该怪谁呢?当然不是那些采用子像素渲染的浏览器,因为最终这是产生最佳结果的方法。

无论如何,这简直是一团糟,我们将在本文的结论中再次讨论这个问题。

Sass 怎么样?

Sass 支持数学运算。这并不是什么新鲜事,实际上是 Sass 最初使用的几件事之一(用于构建基于数学的网格系统)。我们可以告诉 Sass 我们想要将容器的宽度分成 3 个相等的部分。

.list-item {
  float: left;
  width: (100% / 3);
}

我们也可以使用 percentage(..) 函数获得相同的结果:

.list-item {
  float: left;
  width: percentage(1 / 3);
}

在 Ruby 和 LibSass 中,Sass 的精度选项为 5。这实际上是一个问题,因为它非常低;10 会更好,但这并不是默认值(尽管可以配置,但不是很容易)。

此代码将生成以下 CSS:

.list-item {
  float: left;
  width: 33.33333%;
}

这并没有解决我们的浏览器问题,但这确实使编写样式表更容易。我们不仅不必自己处理计算和精度,而且我们还通过实际显示计算使代码更易于阅读和更新。

我认为这是一件好事。

两全其美

到目前为止,我们已经了解到,最好让 Sass 为我们处理计算,而不是硬编码值。现在,最好的方法是让浏览器以它能做到的最佳方式来处理这个问题。为此,可以使用 calc(..) CSS 函数。

.list-item {
  float: left;
  width: calc(100% / 3);
}

这段代码不会编译成任何东西。它以作者编写的形式出现在浏览器中。然后,浏览器负责充分利用它。我会完全诚实地告诉你,我不确定浏览器是否像处理常规值一样处理 calc(..) 值。我认为它们会执行计算,然后进行舍入。有些浏览器似乎将子像素渲染纳入了等式。如果您对此有任何见解,请在评论中分享。

对于不支持 calc(..) 表达式的浏览器(主要是 Internet Explorer 8 和 Opera Mini),我们可以在它之前放置一个表示为 Sass 运算的静态值。这样,我们就能两全其美。

.list-item {
  float: left;
  width: (100% / 3);
  width: calc(100% / 3);
}

结论

让我们快速回顾一下。首先,由于浏览器不一致性和浮点精度缺乏规范,百分比布局很难处理。

然后,硬编码由某种复杂计算产生的值通常不是一个好主意。我们可以让 Sass 计算一个近似值(小数点后 5 位)。

更好的是,我们可以让浏览器计算一个近似值。在一个理想的世界中,当浏览器负责数学和渲染时,它应该能够充分利用它。为了朝着这个方向前进,我们依赖 calc(..) 函数。

这几乎就是目前的情况。没有什么新东西,但我认为快速回顾一下会有所帮助!

关于 CSS 和 Sass 精度的常见问题解答 (FAQ)

CSS 和 Sass 有什么区别?

CSS(层叠样式表)是一种样式表语言,用于描述用 HTML 编写的文档的外观和格式。Sass(语法上令人惊叹的样式表)是一种预处理器脚本语言,它被解释或编译成 CSS。两者之间的关键区别在于 Sass 具有 CSS 中不存在的功能,例如变量、嵌套、mixin、继承等。这些功能使 Sass 比 CSS 更强大、更灵活。

CSS 和 Sass 中的精度是如何工作的?

CSS 和 Sass 中的精度是指样式渲染的细节和准确程度。在 CSS 中,由于缺乏变量和函数,精度通常受到限制。另一方面,Sass 凭借其高级功能,允许更高的精度。例如,您可以为特定颜色或大小定义变量,并在整个样式表中一致地使用它们,确保设计中的精度和一致性。

我可以在任何 Web 项目中使用 Sass 吗?

是的,您可以在任何 Web 项目中使用 Sass。Sass 与所有版本的 CSS 兼容。因此,您可以从 CSS 开始,然后根据需要添加 Sass 功能。但是,请记住,Sass 需要一个预处理器才能将其转换为浏览器可以解释的 CSS。

使用 Sass 比 CSS 的好处是什么?

Sass 比 CSS 提供了几个好处。它允许使用变量、嵌套、mixin 和继承,这可以使您的样式表更井然有序、可重用且易于维护。Sass 还支持数学运算,允许您直接在样式表中计算尺寸和颜色。

如何提高 CSS 或 Sass 代码的精度?

可以通过使用变量来获得一致的值,使用数学运算进行精确计算,以及使用函数和 mixin 来获得可重用的样式来提高 CSS 或 Sass 代码的精度。此外,使用 CSS 重置可以帮助确保不同浏览器之间的一致性。

什么是 CSS 预处理器,为什么 Sass 需要它?

CSS 预处理器是一种脚本语言,它扩展了 CSS 的默认功能。它允许您在样式表中使用变量、嵌套规则、mixin、函数和数学运算。Sass 是一种 CSS 预处理器。它之所以必要,是因为浏览器只能解释 CSS。因此,Sass 代码需要在用于 Web 项目之前编译成 CSS。

Sass 如何帮助编写 DRY(不要重复自己)代码?

Sass 支持变量、mixin 和继承等功能,这有助于编写 DRY 代码。变量允许您一次定义一个值并在多个地方使用它。Mixin 允许您编写可重用的样式,这些样式可以包含在其他规则中。继承允许您从一个选择器共享一组 CSS 属性到另一个选择器。

使用 Sass 的潜在陷阱是什么?

虽然 Sass 提供了许多优点,但它也存在潜在的陷阱。对预处理器的需求可能会增加开发过程的复杂性。此外,如果使用不当,一些 Sass 功能(如嵌套和 mixin)可能会导致 CSS 输出膨胀和效率低下。

如何开始学习和使用 Sass?

网上有很多资源可以学习 Sass。官方 Sass 网站提供了一个全面的入门指南。您还可以在 Web 开发网站和在线学习平台上找到教程。要开始使用 Sass,您需要在开发环境中设置一个 Sass 预处理器。

我可以将现有的 CSS 代码转换为 Sass 吗?

是的,您可以将现有的 CSS 代码转换为 Sass。由于 Sass 是 CSS 的超集,因此任何有效的 CSS 都是有效的 Sass。您可以首先将您的 .css 文件重命名为 .scss(Sassy CSS),然后逐渐开始在代码中使用 Sass 功能。

最新教程 更多>
  • 为什么我的CSS背景图像出现?
    为什么我的CSS背景图像出现?
    故障排除:CSS背景图像未出现 ,您的背景图像尽管遵循教程说明,但您的背景图像仍未加载。图像和样式表位于相同的目录中,但背景仍然是空白的白色帆布。而不是不弃用的,您已经使用了CSS样式: bockent {背景:封闭图像文件名:背景图:url(nickcage.jpg); 如果您的html,css...
    编程 发布于2025-07-06
  • 如何避免Go语言切片时的内存泄漏?
    如何避免Go语言切片时的内存泄漏?
    ,a [j:] ...虽然通常有效,但如果使用指针,可能会导致内存泄漏。这是因为原始的备份阵列保持完整,这意味着新切片外部指针引用的任何对象仍然可能占据内存。 copy(a [i:] 对于k,n:= len(a)-j i,len(a); k
    编程 发布于2025-07-06
  • C++20 Consteval函数中模板参数能否依赖于函数参数?
    C++20 Consteval函数中模板参数能否依赖于函数参数?
    [ consteval函数和模板参数依赖于函数参数在C 17中,模板参数不能依赖一个函数参数,因为编译器仍然需要对非contexexpr futcoriations contim at contexpr function进行评估。 compile time。 C 20引入恒定函数,必须在编译时进行...
    编程 发布于2025-07-06
  • 在程序退出之前,我需要在C ++中明确删除堆的堆分配吗?
    在程序退出之前,我需要在C ++中明确删除堆的堆分配吗?
    在C中的显式删除 在C中的动态内存分配时,开发人员通常会想知道是否有必要在heap-procal extrable exit exit上进行手动调用“ delete”操作员,但开发人员通常会想知道是否需要手动调用“ delete”操作员。本文深入研究了这个主题。 在C主函数中,使用了动态分配变量(H...
    编程 发布于2025-07-06
  • 如何在Java字符串中有效替换多个子字符串?
    如何在Java字符串中有效替换多个子字符串?
    在java 中有效地替换多个substring,需要在需要替换一个字符串中的多个substring的情况下,很容易求助于重复应用字符串的刺激力量。 However, this can be inefficient for large strings or when working with nu...
    编程 发布于2025-07-06
  • 反射动态实现Go接口用于RPC方法探索
    反射动态实现Go接口用于RPC方法探索
    在GO 使用反射来实现定义RPC式方法的界面。例如,考虑一个接口,例如:键入myService接口{ 登录(用户名,密码字符串)(sessionId int,错误错误) helloworld(sessionid int)(hi String,错误错误) } 替代方案而不是依靠反射...
    编程 发布于2025-07-06
  • 如何使用Python理解有效地创建字典?
    如何使用Python理解有效地创建字典?
    在python中,词典综合提供了一种生成新词典的简洁方法。尽管它们与列表综合相似,但存在一些显着差异。与问题所暗示的不同,您无法为钥匙创建字典理解。您必须明确指定键和值。 For example:d = {n: n**2 for n in range(5)}This creates a dicti...
    编程 发布于2025-07-06
  • 如何使用组在MySQL中旋转数据?
    如何使用组在MySQL中旋转数据?
    在关系数据库中使用mySQL组使用mySQL组进行查询结果,在关系数据库中使用MySQL组,转移数据的数据是指重新排列的行和列的重排以增强数据可视化。在这里,我们面对一个共同的挑战:使用组的组将数据从基于行的基于列的转换为基于列。 Let's consider the following ...
    编程 发布于2025-07-06
  • 表单刷新后如何防止重复提交?
    表单刷新后如何防止重复提交?
    在Web开发中预防重复提交 在表格提交后刷新页面时,遇到重复提交的问题是常见的。要解决这个问题,请考虑以下方法: 想象一下具有这样的代码段,看起来像这样的代码段:)){ //数据库操作... 回声“操作完成”; 死(); } ?> ...
    编程 发布于2025-07-06
  • 在PHP中如何高效检测空数组?
    在PHP中如何高效检测空数组?
    在PHP 中检查一个空数组可以通过各种方法在PHP中确定一个空数组。如果需要验证任何数组元素的存在,则PHP的松散键入允许对数组本身进行直接评估:一种更严格的方法涉及使用count()函数: if(count(count($ playerList)=== 0){ //列表为空。 } 对...
    编程 发布于2025-07-06
  • 为什么在我的Linux服务器上安装Archive_Zip后,我找不到“ class \” class \'ziparchive \'错误?
    为什么在我的Linux服务器上安装Archive_Zip后,我找不到“ class \” class \'ziparchive \'错误?
    Class 'ZipArchive' Not Found Error While Installing Archive_Zip on Linux ServerSymptom:When attempting to run a script that utilizes the ZipAr...
    编程 发布于2025-07-06
  • Go web应用何时关闭数据库连接?
    Go web应用何时关闭数据库连接?
    在GO Web Applications中管理数据库连接很少,考虑以下简化的web应用程序代码:出现的问题:何时应在DB连接上调用Close()方法?,该特定方案将自动关闭程序时,该程序将在EXITS EXITS EXITS出现时自动关闭。但是,其他考虑因素可能保证手动处理。选项1:隐式关闭终止数...
    编程 发布于2025-07-06
  • 如何正确使用与PDO参数的查询一样?
    如何正确使用与PDO参数的查询一样?
    在pdo 中使用类似QUERIES在PDO中的Queries时,您可能会遇到类似疑问中描述的问题:此查询也可能不会返回结果,即使$ var1和$ var2包含有效的搜索词。错误在于不正确包含%符号。通过将变量包含在$ params数组中的%符号中,您确保将%字符正确替换到查询中。没有此修改,PDO...
    编程 发布于2025-07-06
  • 如何使用Python有效地以相反顺序读取大型文件?
    如何使用Python有效地以相反顺序读取大型文件?
    在python 反向行读取器生成器 == ord('\ n'): 缓冲区=缓冲区[:-1] 剩余_size- = buf_size lines = buffer.split('\ n'....
    编程 发布于2025-07-06
  • CSS强类型语言解析
    CSS强类型语言解析
    您可以通过其强度或弱输入的方式对编程语言进行分类的方式之一。在这里,“键入”意味着是否在编译时已知变量。一个例子是一个场景,将整数(1)添加到包含整数(“ 1”)的字符串: result = 1 "1";包含整数的字符串可能是由带有许多运动部件的复杂逻辑套件无意间生成的。它也可以是故意从单个真理...
    编程 发布于2025-07-06

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3