过度限定CSS3选择器是否必要以使background-position起作用?

4
我偶然发现了这个 惊人的CSS3 3D动画,并在以下浏览器中查看了它:
  • Safari 9.0.1
  • Chrome 47.0.2526.106
  • Firefox 43.0.1
我正在尝试使用网站提供的代码(这是一个单独的HTML页面,不需要外部文件,只需进行一些有效的外部HTTP引用)。 我注意到有CSS语句.strip .a .strip .b等等...
据我所知,在这些行上指定.strip是过度限定CSS选择器,因为没有其他类似于.a类、.b类等等的情况引入任何歧义 - 在这种情况下,这些类名与id选择器几乎相同,因为每个类名只对应一个HTML标签。
然而,当我从这些选择器中去除 .strip (例如将选择器变为简单的 .a.b 等),相应的 CSS background-position 偏移似乎停止工作,那些行的图像条仅显示图像的前导矩形区域,而不是各自指定的背景位置偏移处的切片。在上述所有浏览器中结果都是相同的。
我在问题末尾提供了代码示例和对应的屏幕截图,展示了产生的伪影。在下面的代码中,我从 .a.b.c.d 行的选择器中去除了 .strip。您可以在下面展示的图像中看到这四个条带似乎没有正确定位。

enter image description here

这是 Webkit、Mozkit 中的一个 bug 吗?还是我对关于这种选择器的 CSS 有所不理解?

body {
  background: #000;
  color: rgb(236, 132, 57)
}
h1 {
  font: small-caps 167% Arial, Helvetica, sans-serif
}
#container {
  text-align: center;
  margin: 0 auto;
  top: 450px;
  width: 550px;
  -moz-perspective: 900px;
  -webkit-perspective: 900
}
#container:hover * {
  -moz-animation-play-state: paused;
  -webkit-animation-play-state: paused
}
#frame {
  width: 33px;
  -moz-transform-style: preserve-3d;
  -webkit-transform-style: preserve-3d;  /* translate must be last */
  -moz-transform: rotateX(35deg) rotateY(45deg) rotateZ(15deg) translate3d(325px, -70px, 50px);
  -webkit-transform: rotateX(35deg) rotateY(45deg) rotateZ(15deg) translate3d(325px, -70px, 50px)
}
.strip {
  -moz-transform-style: preserve-3d;
  -webkit-transform-style: preserve-3d;
  -moz-animation: spin 25s infinite linear;
  -webkit-animation: spin 25s infinite linear
}
.strip div {
  position: absolute;
  background: #000 url(http://baloziproductions.com/thailand-sunrise.jpg);  /* background image is 792px 320px, try with green-hills or thailand-sunrise.jpg */
  border: solid rgb(145, 87, 0);
  border-width: thin 0;
  height: 320px;
  width: 34px;
  opacity: 1;
}
.a {
  background-position: 0 0;
  -moz-transform: rotateY(0deg) translateZ(124px);
  -webkit-transform: rotateY(0deg) translateZ(124px)
}
.b {
  background-position: 759px 0;
  -moz-transform: rotateY(15deg) translateZ(124px);
  -webkit-transform: rotateY(15deg) translateZ(124px)
}
.c {
  background-position: 726px 0;
  -moz-transform: rotateY(30deg) translateZ(124px);
  -webkit-transform: rotateY(30deg) translateZ(124px)
}
.d {
  background-position: 693px 0;
  -moz-transform: rotateY(45deg) translateZ(124px);
  -webkit-transform: rotateY(45deg) translateZ(124px)
}
.strip .e {
  background-position: 660px 0;
  -moz-transform: rotateY(60deg) translateZ(124px);
  -webkit-transform: rotateY(60deg) translateZ(124px)
}
.strip .f {
  background-position: 627px 0;
  -moz-transform: rotateY(75deg) translateZ(124px);
  -webkit-transform: rotateY(75deg) translateZ(124px)
}
.strip .g {
  background-position: 594px 0;
  -moz-transform: rotateY(90deg) translateZ(124px);
  -webkit-transform: rotateY(90deg) translateZ(124px)
}
.strip .h {
  background-position: 561px 0;
  -moz-transform: rotateY(105deg) translateZ(124px);
  -webkit-transform: rotateY(105deg) translateZ(124px)
}
.strip .i {
  background-position: 528px 0;
  -moz-transform: rotateY(120deg) translateZ(124px);
  -webkit-transform: rotateY(120deg) translateZ(124px)
}
.strip .j {
  background-position: 495px 0;
  -moz-transform: rotateY(135deg) translateZ(124px);
  -webkit-transform: rotateY(135deg) translateZ(124px)
}
.strip .k {
  background-position: 462px 0;
  -moz-transform: rotateY(150deg) translateZ(124px);
  -webkit-transform: rotateY(150deg) translateZ(124px)
}
.strip .l {
  background-position: 429px 0;
  -moz-transform: rotateY(165deg) translateZ(124px);
  -webkit-transform: rotateY(165deg) translateZ(124px)
}
.strip .m {
  background-position: 396px 0;
  -moz-transform: rotateY(180deg) translateZ(124px);
  -webkit-transform: rotateY(180deg) translateZ(124px)
}
.strip .n {
  background-position: 363px 0;
  -moz-transform: rotateY(195deg) translateZ(124px);
  -webkit-transform: rotateY(195deg) translateZ(124px)
}
.strip .o {
  background-position: 330px 0;
  -moz-transform: rotateY(210deg) translateZ(124px);
  -webkit-transform: rotateY(210deg) translateZ(124px)
}
.strip .p {
  background-position: 297px 0;
  -moz-transform: rotateY(225deg) translateZ(124px);
  -webkit-transform: rotateY(225deg) translateZ(124px)
}
.strip .q {
  background-position: 264px 0;
  -moz-transform: rotateY(240deg) translateZ(124px);
  -webkit-transform: rotateY(240deg) translateZ(124px)
}
.strip .r {
  background-position: 231px 0;
  -moz-transform: rotateY(255deg) translateZ(124px);
  -webkit-transform: rotateY(255deg) translateZ(124px)
}
.strip .s {
  background-position: 198px 0;
  -moz-transform: rotateY(270deg) translateZ(124px);
  -webkit-transform: rotateY(270deg) translateZ(124px)
}
.strip .t {
  background-position: 165px 0;
  -moz-transform: rotateY(285deg) translateZ(124px);
  -webkit-transform: rotateY(285deg) translateZ(124px)
}
.strip .u {
  background-position: 132px 0;
  -moz-transform: rotateY(300deg) translateZ(124px);
  -webkit-transform: rotateY(300deg) translateZ(124px)
}
.strip .v {
  background-position: 99px 0;
  -moz-transform: rotateY(315deg) translateZ(124px);
  -webkit-transform: rotateY(315deg) translateZ(124px)
}
.strip .w {
  background-position: 66px 0;
  -moz-transform: rotateY(330deg) translateZ(124px);
  -webkit-transform: rotateY(330deg) translateZ(124px)
}
.strip .x {
  background-position: 33px 0;
  -moz-transform: rotateY(345deg) translateZ(124px);
  -webkit-transform: rotateY(345deg) translateZ(124px)
}
@-moz-keyframes spin {
  from {
    -moz-transform: rotateY(0)
  }
  to {
    -moz-transform: rotateY(-360deg)
  }
}
@-webkit-keyframes spin {
  from {
    -webkit-transform: rotateY(0)
  }
  to {
    -webkit-transform: rotateY(-360deg)
  }
}
<div id="container">
  <h1>Image Wrapped Around A Spinning strip</h1>
  <div id="frame">
    <div class="strip">
      <div class="a"></div>
      <div class="b"></div>
      <div class="c"></div>
      <div class="d"></div>
      <div class="e"></div>
      <div class="f"></div>
      <div class="g"></div>
      <div class="h"></div>
      <div class="i"></div>
      <div class="j"></div>
      <div class="k"></div>
      <div class="l"></div>
      <div class="m"></div>
      <div class="n"></div>
      <div class="o"></div>
      <div class="p"></div>
      <div class="q"></div>
      <div class="r"></div>
      <div class="s"></div>
      <div class="t"></div>
      <div class="u"></div>
      <div class="v"></div>
      <div class="w"></div>
      <div class="x"></div>
    </div>
  </div>
</div>

1个回答

4
由于在 .strip div 选择器中指定了背景,因此需要使用过度具体的选择器。
.strip div {
  position: absolute;
  background: #000 url(http://baloziproductions.com/thailand-sunrise.jpg); /* this causes the problem */
  border: solid rgb(145, 87, 0);
  border-width: thin 0;
  height: 320px;
  width: 34px;
  opacity: 1;
}

当使用background缩写属性设置背景时,UA为所有长格式的background-*属性设置值。对于那些显式提供值的长格式属性(如background-colorbackground-image),将使用该值。对于其他所有属性,将使用默认值。 background-position的默认值为0% 0%
引用自W3C规范(重点是我的) “ background”属性是设置样式表中大多数背景属性的简写属性。逗号分隔的项目数定义背景层的数量。对于每个图层,给定有效声明,首先设置每个“ background-image”,“ background-position”,“ background-size”,“ background-repeat”,“ background-origin”,“ background-clip”和“ background-attachment”的相应图层,以该属性的初始值,然后分配此图层在声明中指定的任何显式值。
因此,一个background-position设置已经隐式存在于 .strip div 上。当从 .a .b .c 选择器中删除.strip时,它们与.strip div相比变得不太具体,因此不会修改默认的背景位置。 .strip div的特异性为011,因为它只有一个类选择器和一个类型选择器。 .strip .a的特异性为020,因为它有2个类选择器但没有类型或ID选择器。特异性.a为010,因为它只有一个类选择器但没有类型或ID选择器。 问题片段:(在.strip之前使用缩写属性background.strip div中,而不是在.a.b等之前使用)

body {
  background: #000;
  color: rgb(236, 132, 57)
}
h1 {
  font: small-caps 167% Arial, Helvetica, sans-serif
}
#container {
  text-align: center;
  margin: 0 auto;
  top: 450px;
  width: 550px;
  -moz-perspective: 900px;
  -webkit-perspective: 900
}
#container:hover * {
  -moz-animation-play-state: paused;
  -webkit-animation-play-state: paused
}
#frame {
  width: 33px;
  -moz-transform-style: preserve-3d;
  -webkit-transform-style: preserve-3d;
  -moz-transform: rotateX(35deg) rotateY(45deg) rotateZ(15deg) translate3d(325px, -70px, 50px);
  -webkit-transform: rotateX(35deg) rotateY(45deg) rotateZ(15deg) translate3d(325px, -70px, 50px)
}
.strip {
  -moz-transform-style: preserve-3d;
  -webkit-transform-style: preserve-3d;
  -moz-animation: spin 25s infinite linear;
  -webkit-animation: spin 25s infinite linear
}
.strip div {
  position: absolute;
  background: #000 url(http://baloziproductions.com/thailand-sunrise.jpg);
  border: solid rgb(145, 87, 0);
  border-width: thin 0;
  height: 320px;
  width: 34px;
  opacity: 1;
}
.a {
  background-position: 0 0;
  -moz-transform: rotateY(0deg) translateZ(124px);
  -webkit-transform: rotateY(0deg) translateZ(124px)
}
.b {
  background-position: 759px 0;
  -moz-transform: rotateY(15deg) translateZ(124px);
  -webkit-transform: rotateY(15deg) translateZ(124px)
}
.c {
  background-position: 726px 0;
  -moz-transform: rotateY(30deg) translateZ(124px);
  -webkit-transform: rotateY(30deg) translateZ(124px)
}
.d {
  background-position: 693px 0;
  -moz-transform: rotateY(45deg) translateZ(124px);
  -webkit-transform: rotateY(45deg) translateZ(124px)
}
.e {
  background-position: 660px 0;
  -moz-transform: rotateY(60deg) translateZ(124px);
  -webkit-transform: rotateY(60deg) translateZ(124px)
}
.f {
  background-position: 627px 0;
  -moz-transform: rotateY(75deg) translateZ(124px);
  -webkit-transform: rotateY(75deg) translateZ(124px)
}
.g {
  background-position: 594px 0;
  -moz-transform: rotateY(90deg) translateZ(124px);
  -webkit-transform: rotateY(90deg) translateZ(124px)
}
.h {
  background-position: 561px 0;
  -moz-transform: rotateY(105deg) translateZ(124px);
  -webkit-transform: rotateY(105deg) translateZ(124px)
}
.i {
  background-position: 528px 0;
  -moz-transform: rotateY(120deg) translateZ(124px);
  -webkit-transform: rotateY(120deg) translateZ(124px)
}
.j {
  background-position: 495px 0;
  -moz-transform: rotateY(135deg) translateZ(124px);
  -webkit-transform: rotateY(135deg) translateZ(124px)
}
.k {
  background-position: 462px 0;
  -moz-transform: rotateY(150deg) translateZ(124px);
  -webkit-transform: rotateY(150deg) translateZ(124px)
}
.l {
  background-position: 429px 0;
  -moz-transform: rotateY(165deg) translateZ(124px);
  -webkit-transform: rotateY(165deg) translateZ(124px)
}
.m {
  background-position: 396px 0;
  -moz-transform: rotateY(180deg) translateZ(124px);
  -webkit-transform: rotateY(180deg) translateZ(124px)
}
.n {
  background-position: 363px 0;
  -moz-transform: rotateY(195deg) translateZ(124px);
  -webkit-transform: rotateY(195deg) translateZ(124px)
}
.o {
  background-position: 330px 0;
  -moz-transform: rotateY(210deg) translateZ(124px);
  -webkit-transform: rotateY(210deg) translateZ(124px)
}
.p {
  background-position: 297px 0;
  -moz-transform: rotateY(225deg) translateZ(124px);
  -webkit-transform: rotateY(225deg) translateZ(124px)
}
.q {
  background-position: 264px 0;
  -moz-transform: rotateY(240deg) translateZ(124px);
  -webkit-transform: rotateY(240deg) translateZ(124px)
}
.r {
  background-position: 231px 0;
  -moz-transform: rotateY(255deg) translateZ(124px);
  -webkit-transform: rotateY(255deg) translateZ(124px)
}
.s {
  background-position: 198px 0;
  -moz-transform: rotateY(270deg) translateZ(124px);
  -webkit-transform: rotateY(270deg) translateZ(124px)
}
.t {
  background-position: 165px 0;
  -moz-transform: rotateY(285deg) translateZ(124px);
  -webkit-transform: rotateY(285deg) translateZ(124px)
}
.u {
  background-position: 132px 0;
  -moz-transform: rotateY(300deg) translateZ(124px);
  -webkit-transform: rotateY(300deg) translateZ(124px)
}
.v {
  background-position: 99px 0;
  -moz-transform: rotateY(315deg) translateZ(124px);
  -webkit-transform: rotateY(315deg) translateZ(124px)
}
.w {
  background-position: 66px 0;
  -moz-transform: rotateY(330deg) translateZ(124px);
  -webkit-transform: rotateY(330deg) translateZ(124px)
}
.x {
  background-position: 33px 0;
  -moz-transform: rotateY(345deg) translateZ(124px);
  -webkit-transform: rotateY(345deg) translateZ(124px)
}
@-moz-keyframes spin {
  from {
    -moz-transform: rotateY(0)
  }
  to {
    -moz-transform: rotateY(-360deg)
  }
}
@-webkit-keyframes spin {
  from {
    -webkit-transform: rotateY(0)
  }
  to {
    -webkit-transform: rotateY(-360deg)
  }
}
<div id="container">
  <h1>Image Wrapped Around A Spinning strip</h1>
  <div id="frame">
    <div class="strip">
      <div class="a"></div>
      <div class="b"></div>
      <div class="c"></div>
      <div class="d"></div>
      <div class="e"></div>
      <div class="f"></div>
      <div class="g"></div>
      <div class="h"></div>
      <div class="i"></div>
      <div class="j"></div>
      <div class="k"></div>
      <div class="l"></div>
      <div class="m"></div>
      <div class="n"></div>
      <div class="o"></div>
      <div class="p"></div>
      <div class="q"></div>
      <div class="r"></div>
      <div class="s"></div>
      <div class="t"></div>
      <div class="u"></div>
      <div class="v"></div>
      <div class="w"></div>
      <div class="x"></div>
    </div>
  </div>
</div>


如果直接使用background-colorbackground-image,而不使用简写的background属性,则在更高优先级的选择器中没有background-position时,.strip不需要在.a.b.c等之前出现。

.strip div {
  position: absolute;
  background-color: #000; /* changed */
  background-image: url(http://baloziproductions.com/thailand-sunrise.jpg); /* changed */
  border: solid rgb(145, 87, 0);
  border-width: thin 0;
  height: 320px;
  width: 34px;
  opacity: 1;
}

固定代码片段:(在.strip div中使用长手属性,在.a.b等之前不使用.strip

body {
  background: #000;
  color: rgb(236, 132, 57)
}
h1 {
  font: small-caps 167% Arial, Helvetica, sans-serif
}
#container {
  text-align: center;
  margin: 0 auto;
  top: 450px;
  width: 550px;
  -moz-perspective: 900px;
  -webkit-perspective: 900
}
#container:hover * {
  -moz-animation-play-state: paused;
  -webkit-animation-play-state: paused
}
#frame {
  width: 33px;
  -moz-transform-style: preserve-3d;
  -webkit-transform-style: preserve-3d;
  /* translate must be last */
  -moz-transform: rotateX(35deg) rotateY(45deg) rotateZ(15deg) translate3d(325px, -70px, 50px);
  -webkit-transform: rotateX(35deg) rotateY(45deg) rotateZ(15deg) translate3d(325px, -70px, 50px)
}
.strip {
  -moz-transform-style: preserve-3d;
  -webkit-transform-style: preserve-3d;
  -moz-animation: spin 25s infinite linear;
  -webkit-animation: spin 25s infinite linear
}
.strip div {
  position: absolute;
  background-color: #000;
  background-image: url(http://baloziproductions.com/thailand-sunrise.jpg);
  border: solid rgb(145, 87, 0);
  border-width: thin 0;
  height: 320px;
  width: 34px;
  opacity: 1;
}
.a {
  background-position: 0 0;
  -moz-transform: rotateY(0deg) translateZ(124px);
  -webkit-transform: rotateY(0deg) translateZ(124px)
}
.b {
  background-position: 759px 0;
  -moz-transform: rotateY(15deg) translateZ(124px);
  -webkit-transform: rotateY(15deg) translateZ(124px)
}
.c {
  background-position: 726px 0;
  -moz-transform: rotateY(30deg) translateZ(124px);
  -webkit-transform: rotateY(30deg) translateZ(124px)
}
.d {
  background-position: 693px 0;
  -moz-transform: rotateY(45deg) translateZ(124px);
  -webkit-transform: rotateY(45deg) translateZ(124px)
}
.e {
  background-position: 660px 0;
  -moz-transform: rotateY(60deg) translateZ(124px);
  -webkit-transform: rotateY(60deg) translateZ(124px)
}
.f {
  background-position: 627px 0;
  -moz-transform: rotateY(75deg) translateZ(124px);
  -webkit-transform: rotateY(75deg) translateZ(124px)
}
.g {
  background-position: 594px 0;
  -moz-transform: rotateY(90deg) translateZ(124px);
  -webkit-transform: rotateY(90deg) translateZ(124px)
}
.h {
  background-position: 561px 0;
  -moz-transform: rotateY(105deg) translateZ(124px);
  -webkit-transform: rotateY(105deg) translateZ(124px)
}
.i {
  background-position: 528px 0;
  -moz-transform: rotateY(120deg) translateZ(124px);
  -webkit-transform: rotateY(120deg) translateZ(124px)
}
.j {
  background-position: 495px 0;
  -moz-transform: rotateY(135deg) translateZ(124px);
  -webkit-transform: rotateY(135deg) translateZ(124px)
}
.k {
  background-position: 462px 0;
  -moz-transform: rotateY(150deg) translateZ(124px);
  -webkit-transform: rotateY(150deg) translateZ(124px)
}
.l {
  background-position: 429px 0;
  -moz-transform: rotateY(165deg) translateZ(124px);
  -webkit-transform: rotateY(165deg) translateZ(124px)
}
.m {
  background-position: 396px 0;
  -moz-transform: rotateY(180deg) translateZ(124px);
  -webkit-transform: rotateY(180deg) translateZ(124px)
}
.n {
  background-position: 363px 0;
  -moz-transform: rotateY(195deg) translateZ(124px);
  -webkit-transform: rotateY(195deg) translateZ(124px)
}
.o {
  background-position: 330px 0;
  -moz-transform: rotateY(210deg) translateZ(124px);
  -webkit-transform: rotateY(210deg) translateZ(124px)
}
.p {
  background-position: 297px 0;
  -moz-transform: rotateY(225deg) translateZ(124px);
  -webkit-transform: rotateY(225deg) translateZ(124px)
}
.q {
  background-position: 264px 0;
  -moz-transform: rotateY(240deg) translateZ(124px);
  -webkit-transform: rotateY(240deg) translateZ(124px)
}
.r {
  background-position: 231px 0;
  -moz-transform: rotateY(255deg) translateZ(124px);
  -webkit-transform: rotateY(255deg) translateZ(124px)
}
.s {
  background-position: 198px 0;
  -moz-transform: rotateY(270deg) translateZ(124px);
  -webkit-transform: rotateY(270deg) translateZ(124px)
}
.t {
  background-position: 165px 0;
  -moz-transform: rotateY(285deg) translateZ(124px);
  -webkit-transform: rotateY(285deg) translateZ(124px)
}
.u {
  background-position: 132px 0;
  -moz-transform: rotateY(300deg) translateZ(124px);
  -webkit-transform: rotateY(300deg) translateZ(124px)
}
.v {
  background-position: 99px 0;
  -moz-transform: rotateY(315deg) translateZ(124px);
  -webkit-transform: rotateY(315deg) translateZ(124px)
}
.w {
  background-position: 66px 0;
  -moz-transform: rotateY(330deg) translateZ(124px);
  -webkit-transform: rotateY(330deg) translateZ(124px)
}
.x {
  background-position: 33px 0;
  -moz-transform: rotateY(345deg) translateZ(124px);
  -webkit-transform: rotateY(345deg) translateZ(124px)
}
@-moz-keyframes spin {
  from {
    -moz-transform: rotateY(0)
  }
  to {
    -moz-transform: rotateY(-360deg)
  }
}
@-webkit-keyframes spin {
  from {
    -webkit-transform: rotateY(0)
  }
  to {
    -webkit-transform: rotateY(-360deg)
  }
}
<div id="container">
  <h1>Image Wrapped Around A Spinning strip</h1>
  <div id="frame">
    <div class="strip">
      <div class="a"></div>
      <div class="b"></div>
      <div class="c"></div>
      <div class="d"></div>
      <div class="e"></div>
      <div class="f"></div>
      <div class="g"></div>
      <div class="h"></div>
      <div class="i"></div>
      <div class="j"></div>
      <div class="k"></div>
      <div class="l"></div>
      <div class="m"></div>
      <div class="n"></div>
      <div class="o"></div>
      <div class="p"></div>
      <div class="q"></div>
      <div class="r"></div>
      <div class="s"></div>
      <div class="t"></div>
      <div class="u"></div>
      <div class="v"></div>
      <div class="w"></div>
      <div class="x"></div>
    </div>
  </div>
</div>


1
巨大的帮助。或者,在这种情况下,一种笨拙的、潜在的无知的黑客特异性的方法是从类到ID的更改(.a#a)。我对CSS特异性计算一无所知。CSS声明默认值的转化是一个元分析考虑因素,像您这样经验丰富的专家的分析是真正的教育发生的地方!特异性是如此基础和重要,以至于更多关于CSS的教程应该将这个主题放在最前面。补充信息:https://css-tricks.com/specifics-on-css-specificity/(文章末尾链接到更详细的背景信息)。 - clearlight
1
@nerdistcolony: 是的,将类别更改为 ID 并使用该选择器也可以工作,因为它会在第 100 个位置放置一个 1。此站点提供的特异性计算器也应该有所帮助。很高兴这个答案对你有所帮助 :) - Harry
1
刚刚用我的新账号 (@clearlight) 再次看到这个问题,非常感谢你提供的出色答案。再次感谢。这对于如何思考 CSS 很有教育意义。 - clearlight

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接