Tupi
Tupi

Reputation: 258

Why specifying a class in CSS breaks my code?

I'm developing a small game, where there's a piano generated with pure HTML and CSS. I got the piano from this amazing CodePen from Philip Zastrow. And, while I was trying to adapt the styles, I found a strange behavior I couldn't understand. But, before I explain it, let me tell how the piano works.

It's a <ul> with a class (set), and the keys of the piano are <li> elements. Here's the structure:

<ul class="set">
  <li class="white b"></li>
  <li class="black as"></li>
  <li class="white a"></li>
  <li class="black gs"></li>
  <li class="white g"></li>
  <li class="black fs"></li>
  <li class="white f"></li>
  <li class="white e"></li>
  <li class="black ds"></li>
  <li class="white d"></li>
  <li class="black cs"></li>
  <li class="white c"></li>
</ul>

This is all the HTML in the CodePen (so, the "real" structure of the code is a body with a ul and some li). And the CSS just uses this: some styles are just referred to the li element (and not to the set class). For example, this one:

li {
  margin:0;
  padding:0;
  list-style:none;
  position:relative;
  float:left
}

While this works, that has a problem. My game will have more lists. And I don't want them to get this style.

I thought the solution was easy: I could just specify that the li was inside a set class (because the ul has a set class). Imagine my surprise when I found that this broke the code.

/* This works */
li { /* Some styles */ }
/* But this doesn't */
.set li { /* Some styles */ }

In this snipped, I show you the code using .set li instead of just li (this is the only difference between this snipped and the original code in the CodePen).

* {
  box-sizing:border-box
}

body {
  margin:0;
  background:#222
}

ul {
  height:18.875em;
  width:34em;
  margin:5em auto;
  padding:3em 0 0 3em;
  position:relative;
  border:1px solid #160801;
  border-radius:1em;
  background:linear-gradient(to bottom right,rgba(0,0,0,0.3),rgba(0,0,0,0)),url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/187/vwood.png);
  box-shadow:0 0 50px rgba(0,0,0,0.5) inset,0 1px rgba(212,152,125,0.2) inset,0 5px 15px rgba(0,0,0,0.5)
}

.set li {
  margin:0;
  padding:0;
  list-style:none;
  position:relative;
  float:left
}

ul .white {
  height:16em;
  width:4em;
  z-index:1;
  border-left:1px solid #bbb;
  border-bottom:1px solid #bbb;
  border-radius:0 0 5px 5px;
  box-shadow:-1px 0 0 rgba(255,255,255,0.8) inset,0 0 5px #ccc inset,0 0 3px rgba(0,0,0,0.2);
  background:linear-gradient(to bottom,#eee 0%,#fff 100%)
}

ul .white:active {
  border-top:1px solid #777;
  border-left:1px solid #999;
  border-bottom:1px solid #999;
  box-shadow:2px 0 3px rgba(0,0,0,0.1) inset,-5px 5px 20px rgba(0,0,0,0.2) inset,0 0 3px rgba(0,0,0,0.2);
  background:linear-gradient(to bottom,#fff 0%,#e9e9e9 100%)
}

.black {
  height:8em;
  width:2em;
  margin:0 0 0 -1em;
  z-index:2;
  border:1px solid #000;
  border-radius:0 0 3px 3px;
  box-shadow:-1px -1px 2px rgba(255,255,255,0.2) inset,0 -5px 2px 3px rgba(0,0,0,0.6) inset,0 2px 4px rgba(0,0,0,0.5);
  background:linear-gradient(45deg,#222 0%,#555 100%)
}

.black:active {
  box-shadow:-1px -1px 2px rgba(255,255,255,0.2) inset,0 -2px 2px 3px rgba(0,0,0,0.6) inset,0 1px 2px rgba(0,0,0,0.5);
  background:linear-gradient(to right,#444 0%,#222 100%)
}

.a,.g,.f,.d,.c {
  margin:0 0 0 -1em
}

ul li:first-child {
  border-radius:5px 0 5px 5px
}

ul li:last-child {
  border-radius:0 5px 5px 5px
}
<ul class="set">
  <li class="white b"></li>
  <li class="black as"></li>
  <li class="white a"></li>
  <li class="black gs"></li>
  <li class="white g"></li>
  <li class="black fs"></li>
  <li class="white f"></li>
  <li class="white e"></li>
  <li class="black ds"></li>
    <li class="white d"></li>
    <li class="black cs"></li>
    <li class="white c"></li>
</ul>

I edited all the CSS, so I could use the piano just referring to the set class. Only the .set li doesn't work, all the other declarations work fine. My question is: why?

I'm not asking for the solution: I asked the same in SO in Spanish and someone told me how I could solve the problem (instead of .set li, using .white, .black). But my question is still present: why .set li doesn't work, if the li is inside an element with that class?

Thanks for reading this, and I hope anyone can help me discover why this doesn't work, because I simply don't understand it.

Upvotes: 0

Views: 111

Answers (0)

Related Questions