之前做一个html页面,有一个样式是需要将一个图片始终置于右下角,一开始用绝对定位做好了,可是真正用到微信上时出问题了,原来将div用position:absolute绝对定位其实是相对于当前可视窗口的绝对定位,而当页面长度大于一屏的长度时,这个div就比预想的位置高了,而且会遮挡一些UI控件,很纠结。当时紧急做了两个方案,暂时解决了这个遮挡的问题。最近看《css揭秘》,看到了几个更优的方法,所以想记录下来。

设计图
原设计图

方式1. position:absolute绝对定位方案

  一开始的想法是将图片放在div中,然后设置绝对定位,即可搞定,关键代码如下:

1
2
3
<div id="zanWX" style="position:absolute;right:10px;bottom:0px; z-index: 1000px ;">
<img src="images/zan_wx.png" style="max-height: 186px; max-width: 188px;">
</div>

  具体代码参见报名表1
  在网页端测试一切正常,如图2,但是当放到微信上时,出了bug。如图3,图4。由于页面高度大于手机屏幕高度,初始加载页面时,position:absolute样式的div就只是出现在可视页面的底部,但是当向上滚动会发现,div离真正的页面底端还有很大的距离;而且图片手的位置挡住了年级的填框。

设计图
图2

设计图设计图
图3、4

  当时用了一种笨拙的方式解决这个问题。用js判断当前页面是否滚动到页面底部,如果没有则隐藏图片,如果滚动到底部就展示图片。今天读到《css揭秘》第2章,突然发现有更简单的实现方式。

方式2. background-position的扩展语法方案

  在 CSS 背景与边框(第三版)(http://w3.org/TR/css3-background)中, background-position 属性已经得到扩展,它允许我们指定背景图片距离任 意角的偏移量,只要我们在偏移量前面指定关键字。举例来说,如果想让背 景图片跟右边缘保持 20px 的偏移量,同时跟底边保持 10px 的偏移量,可以 这样做(结果如图5所示):

设计图
图5
1
2
background: url(code-pirate.svg) no-repeat #58a;
background-position: right 20px bottom 10px;

  最后一步,我们还需要提供一个合适的回退方案。因为对上述方案来 说,在不支持 background-position 扩展语法的浏览器中,背景图片会紧 贴在左上角(背景图片的默认位置)。这看起来会很奇怪,而且它会干扰到 文字的可读性(参见图6)。提供一个回退方案也很简单,就是把老套的 bottom right定位值写进background的简写属性中:

设计图
图6

1
2
background: url(code-pirate.svg) no-repeat bottom right #58a;
background-position: right 20px bottom 10px;

在线编辑地址:http://play.csssecrets.io/extended-bg-position
  以上摘自《css揭秘》,受此启发,我决定改一下我之前图片的实现方式。将展示图片的div代码块去掉,给body增加一个名为bdStyle的css样式属性来实现右下角图片定位问题。关键代码如下:

.bdStyle{
        background: url(images/zan_wx.png) no-repeat bottom right #FFFFFF;
        background-size:186px 188px;
        background-position: right 10px bottom 0px;
     }

方式3. background-origin方案

  在给背景图片设置距离某个角的偏移量时,有一种情况极其常见:偏移量与容器的内边距一致。如果采用上面提到的 background-position的扩展语法方案,代码看起来会是这样的:

padding: 10px;
background: url(code-pirate.svg) no-repeat #58a; 
background-position: right 10px bottom 10px;

  虽然也能达到我们想要的效果,但是每次改动内边距的值时,我们需要在三个地方更新,,可以通过一个更简单的办法实现这个需求:让它自动跟着我们设定的内边距走,而不用另外声明偏移量的值。
  默认情况下,background-position 是以 padding box 为准的,这样边 框才不会遮住背景图片。因此,top left默认指的是padding box的左上 角。不过,在背景与边框(第三版)(http://w3.org/TR/css3-background)中, 我们得到了一个新的属性 background-origin,可以用它来改变这种行为。 在默认情况下,它的值是(闭着眼睛也猜得到)padding-box。如果把它的 值改成 content-box(参见下面的代码),我们在 background-position 属 性中使用的边角关键字将会以内容区的边缘作为基准(也就是说,此时背景 图片距离边角的偏移量就跟内边距保持一致了):

padding: 10px;
background: url("code-pirate.svg") no-repeat #58a bottom right; /* 或 100% 100% */ 
background-origin: content-box;

在线编辑地址:http://play.csssecrets.io/background-origin

  它的视觉效果跟上一段代买效果是完全一样的,但我们的代码变得更加 DRY 了。在必要时可以把这两种技巧组合起来!如果你想让偏 移量与内边距稍稍有些不同(比如稍微收敛或超出),那么可以在使用 background-origin: content-box的同时,再通过background-position 的扩展语法来设置这些额外的偏移量。
以上节选自《css揭秘》,受此启发,我决定再次改一下我之前图片的实现方式。将bdStyle的css样式用background-origin方案实现,关键代码如下:

.bdStyle{
        background: url(images/zan_wx.png) no-repeat bottom right #FFFFFF;
        background-size:186px 188px;
        background-origin: content-box;
     }

具体代码参见报名表3

方式4. calc()方案

  假如我们有一个需求:把背景图片定位到距离底边 10px 且 距离右边 20px 的位置。如果我们仍然以左上角偏移的思路来考虑,其实 就是希望它有一个100% - 20px的水平偏移量,以及100% - 10px的垂直 偏移量。谢天谢地,calc() 函数允许我们执行此类运算,它可以完美地在 background-position 属性中使用:

background: url(code-pirate.svg) no-repeat; 
background-position: calc(100% - 20px) calc(100% - 10px);

在线编辑地址:http://play.csssecrets.io/background-position-calc
  以上节选自《css揭秘》。按照这个思路,我修改我自己页面中图片的实现方法,将bdStyle的css样式用calc()方案实现,关键代码如下:

.bdStyle{
        background: url(images/zan_wx.png) no-repeat bottom right #FFFFFF;
        background-size:186px 188px;
        background-position: calc(100% - 10px) calc(100%);
     }

具体代码参见报名表4