65.9K
CodeProject 正在变化。 阅读更多。
Home

精通 CSS3 多重背景

starIconstarIconstarIconstarIconstarIcon

5.00/5 (4投票s)

2012 年 6 月 7 日

CPOL

6分钟阅读

viewsIcon

28499

如何使用 CSS3 的多重背景。

30 天开发一个 Windows 8 应用

我们继续探索 CSS3 阴影的世界。今天我们将重点关注另一个有趣的功能——如何使用 CSS3 的多重背景。

背景组合

有许多原因需要创建多重图像组合来构建你的背景。我认为最重要的原因如下:

  • 减少带宽使用,如果单独图像的大小总和小于合并图层的图像大小(尤其是在图像包含重复图案的情况下),并且
  • 提供一种对不同图层进行独立操作的方式(例如,如果你要实现一些视差效果)。

我相信你可能还有其他合理的论点。微笑 | <img src= " src="https://codeproject.org.cn/script/Forums/Images/smiley_smile.gif" />

经典方法

所以我们需要通过将一些图像叠加在其他图像之上来构建一个多层背景。这个问题通常是如何解决的?这真的很简单:只需为每个图像创建一个容器(例如一个 div 元素),然后使用 CSS 规则为其添加背景。接下来,你可以将一个容器插入另一个容器中,或者将它们并排放置,并应用相应的定位 CSS 规则。这里有一个简单的示例:

<div class="sample1">
    <div class="sea">
        <div class="mermaid"><div class="fishing"></div></div>               

        <div class="fish"></div>
    </div>
</div>

“fishing” 类仅为演示目的而嵌套在“mermaid” 类中。

这里有一些 CSS 样式:

.sample1 .sea, .sample1 .mermaid,
.sample1 .fishing {
    height:300px;
    width:480px;
    position: relative;
}
            
.sample1 .sea {
    background: url(media/sea.png) repeat-x top
left;          
}
            
.sample1 .mermaid {
    background: url(media/mermaid.svg) repeat-x
bottom left;
}
        
.sample1 .fish {
    background: url(media/fish.svg) no-repeat;
    height:70px;
    width:100px;
    left: 30px;
    top: 90px;
    position: absolute;
}
            
.sample1 .fishing {
    background: url(media/fishing.svg) no-repeat
top right 10px;
}

结果

在此示例中,我有三个嵌套的 div 带有背景,还有一个邻居“fish”-div。你可以想象,鱼可以使用 JavaScript 或 CSS3 过渡或动画进行动画处理。

请注意,对于“fishing”类,我使用的是 CSS3 中定义的新 背景定位语法。但目前只有 IE9+ 和 Opera 11+ 支持,而 Firefox 10 或 Chrome 16 还不支持。所以后两者的用户无法捕捉到鱼 不高兴 | <img src= src="https://codeproject.org.cn/script/Forums/Images/smiley_frown.gif" /> /p>

让我们继续。能否简化这个组合?

多重背景

这时,多重背景就派上用场了。这个功能允许你在同一个元素上同时添加 一个以上的背景。看起来是这样的:

<div class="sample2">
    <div class="sea">                    

        <div class="fish"></div>
    </div>
</div>

样式:

.sample2 .sea {
    height:300px;
    width:480px;
    position: relative;
    background-image:  url("media/fishing.svg"), url("media/mermaid.svg"), url("media/sea.png");  
    background-position: top right 10px, bottom left,
top left;
    background-repeat: no-repeat,
repeat-x, repeat-x ;
}
            
.sample2 .fish {
    background: url("media/fish.svg") no-repeat;
    height:70px;
    width:100px;
    left: 30px;
    top: 90px;
    position: absolute;
}

要定义多重背景,您应该使用 `background-image` 规则,以逗号分隔列出您的图像。您还可以使用其他规则为每个图像设置位置、重复模式和其他属性——只需使用逗号分隔的列表为相应的规则编写它们。注意图像的顺序:它们从左到右排列,从最上面的一个开始,到最下面的一个结束。

结果 100% 相同

在一个规则中

如果你不需要你的鱼在一个独立的块中游动,整个背景可以写在一个简单的规则中。

<div class="sample3">
    <div class="sea"></div>
</div>

样式

.sample3 .sea {
    height:300px;
    width:480px;
    position: relative;
    background-image:  url("media/fishing.svg"), url("media/mermaid.svg"), url("media/fish.svg"), url("media/sea.png");  
    background-position: top right 10px, bottom
left,  30px 90px, top left;
    background-repeat: no-repeat,
repeat-x ;
}

我没有再次展示同一张图片,但请相信我——它与上面的两张图片是相等的。再次看看样式,尤其是 `background-repeat` 规则。根据规范,如果列表的一部分被省略,用户代理(浏览器)应该重复现有的列表来填充剩余部分。

在我们的例子中,它等同于以下定义:

background-repeat: no-repeat,
repeat-x, no-repeat, repeat-x;

更短的版本

如果你还记得 CSS 2.1,可以在一个简短的“background”规则中描述背景图像。那么对于多重背景呢?实际上,你也可以使用“background”规则来处理多重背景。

.sample4 .sea {
    height:300px;
    width:480px;
    position: relative;
    background: url("media/fishing.svg") top right 10px no-repeat, 
                url("media/mermaid.svg") bottom left
repeat-x,
                url("media/fish.svg") 30px 90px no-repeat,
                url("media/sea.png")
repeat-x;                
            }

但请注意,除非值等于默认值,否则您无法轻易省略参数。此外,如果您想定义背景颜色,应该将其放在最后一个图层中。

动态图像

我们已经知道了:如果你的背景大部分是静态的——它可能取决于容器的大小(即如果你使用百分比长度,一些图层在调整窗口大小时会移动)——那么多重背景的魔力似乎很有用,因为它确实简化了页面结构。但是,如果你需要用 JavaScript 为某些图层添加动画(移动、旋转等)呢?

我有一个真实的示例—— Yandex 网站(俄罗斯搜索引擎)上的蒲公英主题( Yandex ), YNDX

如果你查看源代码(在 IE 中按 F12 打开开发工具),你会发现类似的代码:

<div class=b-skin-bg sizcache="272" sizset="0">
  <div class=b-fluff-bg sizcache="272" sizset="0">
         <div class=b-fluff__sky sizcache="272" sizset="0">
                 <div style="background-position: 3244px 0px" class=b-fluff__cloud></div>
                 <div style="width: 1200px" class=b-max-width sizcache="214" sizset="0">
                         <div class=b-fluff__placeholder sizcache="302" sizset="0">
                                <div style="bottom: 105px; display: none; left: 940px" class="b-fluff__item
b-fluff_item_3" jQuery1328289994769="30"></div>
                                <div style="bottom: 50px; display: none; left: 879px" class="b-fluff__item
b-fluff_item_3" jQuery1328289994769="31"></div>
                                <div style="bottom: 105px; display: none; left: 940px" class="b-fluff__item
b-fluff_item_3" jQuery1328289994769="32"></div>
                                ...
                         </div>
                 </div>
         </div>
  </div>
</div>

带有“b-fluff-bg”、“b-fluff__cloud”和“b-fluff__item”类的 div 应用了 CSS 规则,添加了叠加的背景图像。带有云的背景从左到右滚动,带有蒲公英种子的背景在屏幕上飞舞。

能否使用 CSS3 多重背景重写这样的组合?实际上可以,但前提是 1) 它在所有目标浏览器中都得到支持,并且 2) 继续阅读 眨眼 | <img src= " src="https://codeproject.org.cn/script/Forums/Images/smiley_wink.gif" />

我们如何使我们的多重背景更具动态性?在内部,浏览器会将每个“background”规则解析为每个属性的单独“background-*”规则。这在你只需要更改一个属性时非常有用。例如,你可以使用“background-position”规则来移动你的图像。但处理多重背景会带来一些权衡:如果你只移动一个图层,你仍然需要为所有图层重写这个规则。

为了动画化我们的海洋背景,我们可以使用以下 JS 代码:

$(document).ready(function() {
    var sea = $(".sample5
.sea")[0];
    var fishesX = 30;
    var fishesY = 90;
    var fishX = 0;
    var fishY = 0;
    var mermaidX = 0;
    var t = 0;
 
    function
animationLoop() {
        fishesY = 90 + Math.floor(30 * Math.sin(t++ / 180.0));
        if(--fishesX
< 0) fishesX = 480;
        mermaidX += 0.5;
        if(mermaidX >
480) mermaidX = 0;
        fishY = -10 + (10 * Math.cos(t * 0.091));
        fishX = 10 + (5 * Math.sin(t * 0.07));
 
        sea.style.backgroundPosition =
"top
" + fishY + "px right " + fishX + "px,
" + mermaidX + "px bottom," + fishesX + "px
" + fishesY + "px, top left";
 
       
window.requestAnimFrame(animationLoop);
    }
    animationLoop();
});

其中

window.requestAnimFrame = (function() {
    return 
        window.requestAnimationFrame
|| 
        window.msRequestAnimationFrame
||
       
window.mozRequestAnimationFrame || 
        window.oRequestAnimationFrame
|| 
        window.webkitRequestAnimationFrame
|| 
        (function(callback) {
window.setTimeout(callback, 1000 / 60); });
})();

结果(视频

你也可以使用 CSS3 过渡或动画,但这将是一个单独的讨论话题。

视差和交互性

最后,使用类似的技术,你可以轻松地为你的背景添加一些视差效果或其他交互效果。

在此插入视频播放器

<iframe width="420" height="315" src="http://www.youtube.com/embed/AzHb82fjpR8?rel=0" frameborder="0" allowfullscreen></iframe>

多重背景在这种场景下非常有用,而且当我们只讨论背景而不是内容时,使用它们绝对是一种避免用复杂不必要的元素充斥 HTML 代码的好方法。但正如我所说,如果你需要构建一个复杂且动态的背景,会有一些权衡:你无法通过 ID、类或任何其他参数访问单独的图层。你需要记住代码中图层的顺序,并且要只更改一个图层的属性,你将需要构建一个描述所有图层该属性的字符串。要更新一个图层,你需要更新整个组合。

sea.style.backgroundPosition = "top
" + fishY + "px right " + fishX + "px,
" + mermaidX + "px bottom," + fishesX + "px
" + fishesY + "px, top left";

我相信有可能构建一个漂亮且有用的 JS 库,它可以虚拟化所有这些图层,并提供一种简单的方式来更改单个图层的属性,同时保持你的 HTML 代码和 DOM 的整洁。

兼容性

所有现代浏览器,包括 IE10 和 9 支持多重背景。你也可以使用像 Modernizr 这样的工具来为旧浏览器提供一定程度的兼容性,例如通过提供备用背景。正如 Chris Coyier 在他的 关于多重背景堆叠顺序的文章 中所写,你可以使用以下方法:

.multiplebgs body {
   /* Awesome multiple BG declarations
that transcend reality and impress chicks */
}
.no-multiplebgs body {
  /* laaaaaame fallback */
}

如果你对使用 JavaScript 为新的 CSS3 规则提供向后兼容性感到困惑,你可以只定义两次 `background` 属性(但这种方法可能会在现代浏览器中导致不必要的下载,具体取决于它们如何处理这些规则)。

/* multiple bg fallback */
background: #000 url(...) ...;
/* Awesome multiple BG declarations
that transcend reality and impress chicks */
background url(...), url(...), url(...), #000 url(...);

最后,如果你想知道:是的,你可以在使用 HTML 和 JavaScript 构建的 Windows 8 metro 风格应用中使用多重背景。

附注:还可以查看 Alax Walker 的这篇关于 蝉原理 的精彩文章。

注意

本文讨论的 CSS 属性定义在 CSS3 背景和边框 模块中,该模块目前处于工作草案状态。虽然它看起来相当稳定,但细节仍可能发生变化。

© . All rights reserved.