使用::before伪元素消除CSS background系列属性异常

昨晚在设置博客的背景图片,对Indite主题作了一阵魔改之后利用background-image等CSS属性在<body>上实现。

本来为移动端和桌面端分别准备了几张图片,并配合PHP随机选择url,再利用响应式布局和background-size: cover属性值实现了“将图片缩放成将完全覆盖背景定位区域的最小大小”,并且保持纵横比(通俗一点就是,背景图的显示尺寸覆盖完页面的宽和高,并且没有白边);同时使图片位置保持在屏幕中央,利用了background-attachment: fixed。电脑上调试一切正常。

但在移动端上出现了问题。Chrome和微信内置的浏览器都没有遵照我设置的CSS属性,图片被拉伸和过度放大,也没有保持居中。在caniuse.com(一个Web开发使用的各种特性在不同浏览器上的受支持情况的查询网站)上一查,果然有问题。首先,background-size若只设置一个值(宽),在某些使用旧草案的webkit内核浏览器上第二个值会直接复制第一个,而不是设置为autocovercontain的属性亦表现异常;background-attachment也不被Safari等移动端浏览器支持。

鉴于此,我们考虑通过设置::before伪元素的属性“曲线救国”。::before::after伪元素可以在实际HTML元素前、后添加特定内容,并且像普通元素一样设置各种CSS属性。使用时必须在CSS中设置属性content: "伪元素内容",否则会被忽略。

所以,我们可以设置body::before伪元素的背景图像,并将其定位设置为position: fixed实现固定位置,再设置宽高覆盖页面等,就可有效消除异常。就像这样:

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
body::before { content: ""; position: fixed; top: 0; left: 0; width: 100%; height: 100%; z-index: -1; background-position: center; background-repeat: no-repeat; background-size: cover; }

图片地址在响应式内容中:

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
@media screen and (max-width: 768px) { body::before { background-image: url("/wp-content/uploads/2021/07/<?php echo ['决战群玉阁_s.jpg', '玉扉绕尘歌_s.jpg', '花海双星_s.jpg', '陨石_s.jpg'][rand(0, 3)]; ?>"); } } @media screen and (min-width: 769px) { body::before { background-image: url("/wp-content/uploads/2021/07/<?php echo ['决战群玉阁_h.jpg', '和煦希望之风_h.jpg', '海灯节_h.jpg', '花海双星_h.jpg', '钟离_h.jpg', '陨石_h.jpg', '雪山_h.jpg'][rand(0, 6)]; ?>"); } }

(其实在<body>开头加个<img>并且设置各项属性可能更灵活一点)

(但那样就用不了background-size: cover这么美妙的属性值了)

  • 2021年7月20日