[CSS]A Tale of CSS and Sass Precision(译)_html/css_WEB-ITnose
原文地址:http://www.sitepoint.com/a-tale-of-css-and-sass-precision/
在 Edenspiekermann,我们通过严格的代码审查来确保我们提交的代码足够完善。而关于数字的模糊性是我经常遇到的一个问题,特别是有小数点的数字。因此,在这里我会用一篇简单的文章阐明这个问题。
初始设置
为了使文章更容易理解,在进一步深入之前我们先用一个小小的代码块作为例子。
.list-item { float: left; width: 33%;}
有什么问题呢?
或许你会问,这个代码块有什么问题吗?表面上看来,确实没什么问题,这不就是一个典型的三列网格布局吗?
虽然 33% + 33% +33% 并不等于 100% 而是99 %。且在大多数情况下这个小小的差距并不会造成任何影响,但是当它作用在直线布局时,1% 的差距可能会造成很大的影响。要知道在 1400px及以上的容器中, 1% 的差距至少就是 14px了,这可是一个很大的间隙。
为什么我们不尝试移动一下小数点使它更加精确呢?我们可以把间隙减小到 1.4px甚至是 0.14px,这个距离可不会使我们烦恼了。那我们应该这样写:
.list-item { float: left; width: 33.33%;}
效果好了一些,但仍然不完美。这个问题已经在 John Albin Wilkins 发布的文章“ Responsive Design’s Dirty Little Secret”中被深入研究过了。如果你没读过这篇精彩的文章,你应该去读一下。
浏览器不能处理么?
这时候你可能会想,为什么浏览器就不能完美的解决这个问题呢?事实上,CSS 规范中并没有指定浏览器应该保留多少位精度的小数点。当 CSS 规范没有指定一项细则的时候,可以肯定的是每个浏览器都会有它自己的一套标准。
接下来引用一下上述文章中的段落:
在6列网格布局中,每列的宽度都是 100% ÷ 6 = 16.666667%。那么在 1000px 的视图中(只是为了使我们的计算更加容易),计算结果就是每列的宽度为 166.66667px。因为并没有明确的文档规定,所以浏览器厂商可以制定自己的规则。如果浏览器精确到最近的整数,在这个例子中,也即是 167px。但是因为 167 * 6 =1022px,因此在视图中我们无法给这 6 列提供足够的空间。相反的,如果浏览器把每列精确到 166px,那么就会在我们的视图中造成 4px 的间隙。
– John Albin Wilkins
这就是事实。旧版本的 IE 浏览器(主要是 IE6 和 IE7)会把数值转换为最接近的整数,从而导致布局缺陷。Webkit 浏览器会向下取整,这样防止布局的错位但会留下额外的空间。Opera(至少在以前的渲染引擎中)则会做一些奇怪的让人不解的东西。话说回来,关于这方面的规则并没有制定出来,所以又能责怪谁呢?不能怪浏览器使用的是像素来 渲染页面,这是肯定的,因此目前看来这是最好的结果。
无论如何,它几乎一团糟,我们会在文章结论部分再讨论这个问题。
那么 Sass 呢?
Sass 支持数字运算。这并不是新的领域并且实际上也用于 Sass 的新项目 (用于构建数字基础网格系统)。而我们能够做的就是告诉 Sass 我们希望把容器平分为三个部分。
.list-item { float: left; width: (100% / 3);}
我们也可以通过百分比函数 percentage(..)求得相同的结果。
.list-item { float: left; width: percentage(1 / 3);}
无论使用 Ruby 还是 LibSass,都可以保留五位 小数。这实际上是一个 问题,因为精度太低了。如果保留 10 位小数会更好,可惜这不是默认设置(尽管可以更改设置,但这并不是一个容易的方法)。
上面的代码产生的 CSS 效果如下:
.list-item { float: left; width: 33.33333%;}
这并不能解决我们的浏览器问题,但这简化了我们的样式表。通过所见即所得的计算模式,不仅使得我们不需要自己计算精度值,同时使得代码更加易读和维护。
不得不说这是一件好事。
两全其美
目前为止,我们已经了解到让 Sass 处理这些计算比我们自己手动算出来的数值精确多了。现在,最好的方法是让浏览器自己用最好的方法去处理这个运算。因此,我们可以使用 CSS 的 calc(..)函数。
.list-item { float: left; width: calc(100% / 3);}
这个代码块并不会被编译成其他东西,它由浏览器编译,然后由浏览器选择最佳方案。我可以坦诚的告诉你,我并不了解浏览器处理 calc(..)函数是否是和其他函数一样的流程。我推测它先执行运算,然后取整。有些浏览器似乎会把像素也带入计算。如果您有这方面的见解,欢迎在评论中分享。
对于那些 不支持 calc(..)表达式的浏览器 (主要是 IE8 和 Opera Mini),我们可以在 Sass 操作前放入一个静态表达式,通过这种方式达到平衡。
.list-item { float: left; width: (100% / 3); width: calc(100% / 3);}
结论
让我们回顾一下。首先,因为浏览器之前的差异性和缺乏统一的标准,所以基于百分比的布局很难处理。
其次,通过一些复杂运算而导致的硬编码值通常也不是一个好主意。我们可以通过 Sass 计算出近似值(浮点后五位数)。
更好的方法是,我们让浏览器自己计算近似值。在理想的情况下,浏览器可以同时掌控算数和渲染,那么它能生成最好的方案。朝这个方向前进,我们需要依赖 calc(..)函数的使用。
目前为止就讲这么多了。没有新的内容,但我想一个快速的回顾会对你有帮助的!
推荐阅读
-
[译](深入了解CSS Box Shadow)_html/css_WEB-ITnose
-
[CSS]Flexbox and Truncated Text(译)_html/css_WEB-ITnose
-
[CSS]Flexbox and Truncated Text(译)_html/css_WEB-ITnose
-
CSS 强化装备!Sass 整理笔记_html/css_WEB-ITnose
-
强悍的CSS工具组合:Blueprint, Sass, Compass_html/css_WEB-ITnose
-
【译】建立更好的可访问性原语_html/css_WEB-ITnose
-
css扩展技术:Less和Sass的区别_html/css_WEB-ITnose
-
SASS使用总结_html/css_WEB-ITnose
-
[CSS3] Using CSS’s object-fit and object-position Properties(译)_html/css_WEB-ITnose
-
CSS 强化装备!Sass 整理笔记_html/css_WEB-ITnose