Why is my first-child selector not working on the first element in a selection with a specified class?

StackOverflow https://stackoverflow.com/questions/18577994

Question

I'm a little clueless as to the correct use of first-child.

I have a (dynamically generated) element, which eventually will include:

<h1>
  <a>Foo</a>
  <a.trigger>Trigger A</a>
  <a.trigger>Trigger B</a>
  <span.bar>Bar</span>
</h1>

I need to style both the trigger links. This is what I'm doing:

.ui-collapsible-tabs.ui-dynamic-tabs .ui-collapsible-heading a.trigger {
  background: none repeat scroll 0 0 transparent;
  border: 0 none;
  border-radius: 0;
  box-shadow: none;
  position: absolute;
  right: 2em;
  height: 100%;
  top: 0;
  width: 2em;
}
.ui-collapsible-tabs.ui-dynamic-tabs .ui-collapsible-heading a.trigger:first-child {
  right: 0;
  background-color: red !important;
  border-right: 1px solid red;
}

I have tried both a.trigger:first-child and a.trigger:nth-of-type(1) but I'm not able to override the CSS set by the first rule. Both selectors have same specificity, too, so that cannot be the reason.

Question:
I guess I'm missing something obvious... maybe someone can help me out. Thanks!

Was it helpful?

Solution

:first-child matches the first child of its parent. Your first a.trigger is not the first child — that would be the classless a before it.

:first-of-type and :nth-of-type(1), which are equivalent, match the first element of its type within its parent. In this case, your classless a is also the first a of its parent, making your first a.trigger the second a element.

Is your given structure how your dynamic element will always be generated? If so, you can simply select a.trigger:nth-child(2) instead of a.trigger:first-child:

.ui-collapsible-tabs.ui-dynamic-tabs .ui-collapsible-heading a.trigger:nth-child(2) {
  right: 0;
  background-color: red !important;
  border-right: 1px solid red;
}

Or you can try a + a.trigger:

.ui-collapsible-tabs.ui-dynamic-tabs .ui-collapsible-heading a + a.trigger {
  right: 0;
  background-color: red !important;
  border-right: 1px solid red;
}

(That !important probably isn't needed by the way.)

Otherwise if you need to select the first a.trigger in general you will need to order your declarations differently and change up your selectors a bit:

.ui-collapsible-tabs.ui-dynamic-tabs .ui-collapsible-heading a.trigger {
  background: none repeat scroll 0 0 transparent;
  background-color: red !important;
  border: 0 none;
  border-right: 1px solid red;
  border-radius: 0;
  box-shadow: none;
  position: absolute;
  right: 0;
  height: 100%;
  top: 0;
  width: 2em;
}
.ui-collapsible-tabs.ui-dynamic-tabs .ui-collapsible-heading a.trigger + a.trigger {
  right: 2em;
  background-color: transparent;
  border-right: 0 none;
}

If your two a.triggers aren't always adjacent, replace + with ~.

The generic solution is covered in detail here.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top