4

When adding a new style rule for an element, the selector that Chrome generates contains the entire hierarchy instead of just the class name.

For example:

<body>
      <div class="container">
           <span class="helper"></span>
      </div>
</body>

Adding a new style rule for .helper will generate a selector like body > div > span instead of just .helper. Why is this?

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
Roee Yossef
  • 455
  • 5
  • 16

2 Answers2

3

It's not possible to give an exact analysis of a browser's implementation unless I look at the source itself. But what I can say is that the browser needs to ensure that the style rule that you add will only apply to that specific element in the working DOM, and classes, whose purpose is to group one or more related elements, are not very well-suited for this purpose.

Because of how classes work, the browser can't assume that your class is only assigned to that span element, because it doesn't know how you author your HTML. The example given by NichoDiaz illustrates a simple but valid example of this: a .helper may not necessarily be a body > div > span, because it could very well be a body > div > div > span instead, either now or later.

So instead of making that assumption about the helper class (even though in your DOM only one element has it), it makes an assumption about the structure of your elements instead, which is far more reliable. Since it sees that there is only one span that is a child of a div that is a child of body, it generates the selector body > div > span for the element for which you've chosen to add a style rule. (Presumably, the reason why it starts with body > instead of html > body > is because body is always a child of html, which makes that additional constraint totally redundant.)

Of course, once you add a second span element, the style rule will apply to that element as well. Again the browser cannot anticipate this, but you can easily modify the rule to add :nth-child(1) to the end of the selector if you don't want the style rule applying to that new element.

If you add the second span element before creating a new style rule on the first, you'll see that the browser generates a slightly more specific selector, body > div > span:nth-child(1). If it had tried to generate a selector using .helper and not :nth-child(1), i.e. body > div > span.helper, it would match both elements, which is clearly not the intended result of highlighting one element and adding a style rule for that specific element.

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
  • +1 this makes sense, though in most debugging cases I'd just edit the `.helper` rule properties to affect all elements that match the rule, or just edit the element's style to affect a single element. The "New rule" button seems more useful to add custom rules instead of duplicating an existing rule/creating a single element rule. – Fabrício Matté Mar 28 '14 at 04:47
  • @Fabrício Matté: You're right, I forgot that there's an option to edit an element's style. In that case, perhaps the browser is simply trying to ensure the rule doesn't unintentionally match other elements when it is first created, so it constructs a selector that will only match that element and uses it as a placeholder. – BoltClock Mar 28 '14 at 04:54
  • @Fabrício Matté: There's also the issue of cascading - `element.style` is added as an inline style rather than an internal stylesheet, although I'm not sure how that might be perceived as a problem by most users. – BoltClock Mar 28 '14 at 04:56
  • BoltClock - what you say is reasonable, but how come it just began to behave like that ? i cant recall that behaviour in the past... – Roee Yossef Mar 28 '14 at 15:00
0

There are multiple reasons this could be happening. Without knowing the exact attributes being taken its hard to tell. Also seeing your css would help as well.

To the best I understand you are asking why when you <span class"helper"> it takes its parent div and parent body attributes as well.

This could be because it is itself a child of body and div

Another logical explanation here is a working example on jsfiddle

Depending on your elements you could have something conflicting. In the case of my example the !important tag is added giving its color attribute precedence over the span class But in the next line it applies fine.

<body>
      <div class="container">
           <span class="helper">I am being applied</span>
          <div>
              <span class="helper">I am helper but i am not red</span>
          </div>    
      </div>
</body>

body > div > span {
    color: red !important;
}
.helper { color: green }
wuno
  • 9,547
  • 19
  • 96
  • 180