1

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!

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
frequent
  • 27,643
  • 59
  • 181
  • 333

1 Answers1

3

: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.

Community
  • 1
  • 1
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
  • ah, so first-child only matches elements, not any classes I set on them? – frequent Sep 02 '13 at 17:12
  • 1
    @frequent: Yes. 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`. – BoltClock Sep 02 '13 at 17:14
  • 1
    I can tell you like these CSS selector questions. You really jump on them fast boltclock. 1+ – Josh Crozier Sep 02 '13 at 17:15
  • @BoltClock: there is either 1 trigger, 2 triggers or none. let see if it works. – frequent Sep 02 '13 at 17:16
  • 1
    @Josh C: I call it my specialty tag :) If you look at my profile you'll see [css-selectors] featured very prominently. – BoltClock Sep 02 '13 at 17:23