7

我找到了这个 CSS 缩小器(http://www.lotterypost.com/css-compress.aspx)。该页面底部有一个部分标记为“CSS Compressor 故意不做什么?” 有四件事,其中两件事我不明白为什么它们可能具有破坏性:

将单个边距、填充或边框样式组合到一个属性中。

  margin-top: 10px; 
  margin-right: 0; 
  margin-bottom: 8px;
  margin-left: 30px;

变成

  margin: 10px 0 8px 30px;

并组合在不同样式块中指定的同一元素的样式。

#element {
   margin: 0;
}

#element {
   color: #000000;
}

变成

#element {
   margin: 0;
   color: #000000;
}

我认为 CSSTidy 做到了这两点。上面的网页是否正确?是否存在这些类型的缩小可能会出现问题的情况?

4

3 回答 3

8

我是这个问题 ( http://www.lotterypost.com/css-compress.aspx ) 主题的 CSS Compressor 的开发人员,所以我将举例说明压缩器如何破坏 CSS如果工具主动重写它,则级联。

在样式表中有多种定位元素的方法,并且由于 CSS 压缩器不熟悉页面的 DOM 结构、类、id 等,因此压缩器无法知道是否有跨括号的优化定义是否会中断。

例如,一个简单的 HTML 结构:

<div class="normal centered">
    <p>Hello world.</p>
</div>

还有一些 CSS:

div.normal p {
    margin: 10px 0 10px 0;
}

div.centered p {
    margin: 10px auto;
}

div.normal p {
    margin-bottom: 5px;
}

压缩的代码将生成一个居中的段落,其上边距为 10px,下边距为 5px。

如果您通过 CSS Compressor 运行 CSS 样式,您将获得以下代码,该代码保持原始未压缩样式的顺序和级联。

div.normal p{margin:10px 0}div.centered p{margin:10px auto}div.normal p{margin-bottom:5px}

假设您想通过结合两个div.normal p定义的边距来进一步压缩样式。它们都具有完全相同的选择器,并且它们似乎对底部边距进行了多余的样式设置。

有两种方法可以组合边距:您可以将两个边距定义组合到第一个(顶部)div.normal p样式中,或者将它们组合到最后一个(底部)样式中。让我们尝试两种方式。

如果您将边距组合到第一个(顶部)div.normal p样式中,您会得到:

div.normal p{margin:10px 0 5px}div.centered p{margin:10px auto}

以这种方式组合边距的结果将导致底部边距被错误地设置为 10px,因为“居中”类将覆盖底部边距(因为“居中”样式定义现在出现在级联的后面)。

如果您将边距组合到最后一个(底部)div.normal p样式中,您会得到:

div.centered p{margin:10px auto}div.normal p{margin:10px 0 5px}

以这种方式组合边距的结果将导致段落不再显示为居中,因为底部的“p”定义将覆盖“居中”类中定义的“auto”的左右边距。

所以我们可以看到,通过组合即使具有完全相同的选择器的样式定义也会导致一些非常糟糕的问题。

你个人会写这样的代码吗?也许也许不是。由于级联的各种“权重”规则,有可能在不知不觉中陷入这种类型的代码陷阱。

此外,鉴于在当今的网页中,经常将多个 CSS 文件合并到一个文件中以减少下载量,因此很容易想象 CSS 压缩器通过重写多个样式表(可能由不同的人编写)一起附加到一个文件中。

事实上,我在我的网站Lottery Post上为这个场景编写了 CSS 压缩器。每个网页都有许多支持各种 jQuery 和其他组件的样式表,并且 CSS 压缩器用于将所有这些样式表自动压缩到一个下载中。网站上的所有页面至少有 10 种不同的样式表组合在一起,而且大多数页面不止这些。

例如,如果您查看 CSS Compressor 页面本身背后的代码,您会发现头部的主要样式表如下所示:

<link rel="stylesheet" href="http://lp.vg/css/d11019.0/j2HKnp0oKDOVoos8SA3Bpy3UHd7cAuftiXRBTKCt95r9plCnvTtBMU2BY2PoOQDEUlKCgDn83h16Tv4jbcCeZ(gupKbOQ9ko(TcspLAluwgBqrAjEhOyXvkhqHA(h5WFDypZDK2TIr(xEXVZtX7UANdFp6n1xfnxqIMR8awqGE)vrwUgY2hrCGNNTt1xV7R1LtCSfF46qdH1YQr2iA38r1SQjAgHze(9" />

URL 中的 gobbledeegook 实际上是一个加密字符串,其中包含要在服务器上组合的所有样式表。服务器压缩它们并缓存结果。

该样式表调用的节省空间和时间的技术包括:

  • 将许多样式表组合到一个文件/下载中,只需将它们全部附加在一起
  • 使用 CSS Compressor 压缩组合样式表(不会弄乱级联!)
  • 使用不同的域名(lp.vg)进行样式表下载,提高了浏览器的并行下载能力
  • 使用非常短的域名 (lp.vg)
  • GZip 压缩应用于 Web 服务器上的样式表
  • 样式表的版本号嵌入到 URL (".../d11019.0/...") 中,因此如果多个样式表中的任何一个样式发生更改,我可以更改版本号和浏览器永远不会使用它缓存的版本。(请注意,版本号应该是 URL 路径的一部分,而不是查询字符串,因为某些代理服务器不会查看查询字符串来确定是否应从缓存中检索页面。)

我希望这能更好地解释事情并对那些希望提高页面性能的人有所帮助!

-托德

更多信息:

为了补充以上内容,想象一下如果我们以您的颜色为例,并将样式定义与相同的选择器结合起来。

以下是一些未压缩的样式:

div.normal p {
    margin: 10px 0 10px 0;
}

div.centered p {
    margin: 10px auto;
    color: blue;
}

div.normal p {
    color: black;
}

CSS Compressor 产生以下输出:

div.normal p{margin:10px 0}div.centered p{margin:10px auto;color:blue}div.normal p{color:#000}

如果我们要应用具有相同选择器的样式定义的积极组合,我们将得到以下代码。

方法 1将两者结合到第一个定义中,会错误地将文本颜色变为蓝色:

div.normal p{margin:10px 0;color:#000}div.centered p{margin:10px auto;color:blue}

方法 2将两者结合到第二个定义中,会错误地使文本左对齐:

div.centered p{margin:10px auto;color:blue}div.normal p{margin:10px 0;color:#000}

唯一一次将样式定义与相同的选择器组合是 100% 无错误的,是定义一个接一个地直接出现,但在其他所有情况下,这种技术都有破坏样式级联的风险。

我无法想象任何开发人员都会以这种方式编写代码的情况(两个样式定义具有完全相同的选择器,一个紧接着另一个),因此我得出结论,编写代码所需的工作量以及可能压缩机中的另一个故障点是不值得的。

坦率地说,我会非常关心一个 CSS 压缩器,它可以组合来自不同定义块的样式,因为级联是一个非常脆弱的东西,而且极易破坏级联。

于 2011-10-20T15:42:56.980 回答
2

该页面有一个关于“未使用原因”的部分,描述了它为什么不做这两件事

最重要的是,我认为它不会尝试做这些事情,因为它不是一个完整的 CSS 解析器/解释器,并且会开始像 CSS 条件块这样的东西。

于 2011-10-18T17:46:45.887 回答
0

我认为“破坏性”是指“CSS 无法按预期工作”。

结合诸如您的第一个示例之类的长手规则可以完全没有任何不良影响。

在没有媒体块或其他花哨的东西的普通旧样式表中,第二个示例也不会引起任何问题。

#2 有风险的原因是因为更改规则的顺序,或者在不考虑级联的情况下将规则折叠在一起,可能会导致损坏。

一些 CSS 压缩器可以按字母顺序或选择器类型重新排序规则。这些是非常冒险的,因为移动规则可能会破坏作者创建的级联行为。

像 YUI 压缩器这样的压缩器不会做任何这些,而是​​选择更安全的策略,比如删除空格、多余的分号和零等。

随着更多的 CSS 包含媒体块和其他 CSS3 代码,许多当前的 CSS 压缩器可能根本无法正常工作。大多数人没有合适的词法分析器来解析代码——他们使用上下文感知逐字节(Tidy)或正则表达式(其余大部分)来处理代码。

在选择压缩器时,我建议找到可以在本地执行并且有良好测试套件支持的东西,这样您就可以看到哪些情况是(和未)正确处理的。

于 2011-10-18T18:01:21.550 回答