2

I've seen answers suggesting using first child pseudo selector using the following formats:

/* Type */
P:first-child {
   margin:0px;
}

/* Class */
.myClass:first-child {
   margin:0px;
}

/* ID */
#myDiv:first-child {
   margin:0px;
}

In my case I'm selecting by ID. I've seen only a few using an ID. In my code I can't get it to work unless I put a space in between the ID and pseudo-class like so:

#myDiv :first-child {
   margin:0px;
}

Is this correct?

Here is the code I'm working with:

<div id="richText59">
    <UL>
      <LI>
        <FONT FACE="Verdana" COLOR="#000000" LETTERSPACING="0" KERNING="1" style="font-size:12px">Bullet List</FONT>
      </LI>
    </UL>
</div>

<div id="RichText808">
    <P ALIGN="left">
      <FONT FACE="Verdana" COLOR="#000000" LETTERSPACING="0" KERNING="1" style="font-size:12px">
        <B>
          <I>Rich Text</I>
        </B>
      </FONT>
    </P>
    <P ALIGN="left">
      <FONT FACE="Verdana" COLOR="#000000" LETTERSPACING="0" KERNING="1" style="font-size:12px">
        <B>
          <I>paragraph two</I>
        </B>
      </FONT>
    </P>
</div>

CSS:

#RichText808  {
    position:absolute;
    top:107px;
    left:35px;
    width:240px;
    display:inline-block;
    height:166px;
    display:inline-block;
    margin-top:-0.2em;
    margin-top:0;
}

#richText59  {
    position:absolute;
    top:107px;
    left:335px;
    width:240px;
    display:inline-block;
    height:166px;
    display:inline-block;
    margin-top:-0.2em;
}

In the HTML markup above, the contents of the div will change. I don't control the contents. The problem is that the content of the div is pushed down by around 10px.

By using the first-child selector I am able to remove the margin that pushes the content down. So yes, I do have the ID of the container element but no control over the contents of that element.

enter image description here

1.21 gigawatts
  • 16,517
  • 32
  • 123
  • 231
  • Please show your HTML and indicate which element you are trying to select. –  Sep 29 '16 at 07:38
  • I've added my HTML, CSS and more background information. – 1.21 gigawatts Sep 29 '16 at 07:43
  • 2
    Why are you using the `` element? That was deprecated like a decade ago. –  Sep 29 '16 at 07:45
  • Your HTML has no element with ID of `myDiv`. Also, you did not indicate which element(s) you are trying to target. Minor point, but why do you have duplicate `display` properties in your CSS rules? –  Sep 29 '16 at 07:45
  • The correct term is "ID selector", not "identity selector". –  Sep 29 '16 at 07:49
  • The user enters content and that HTML is placed inside an element I have control of and can target. The content is being pushed down. I've added an screenshot. Since the content can be paragraph, ul, ol or other type I need to target the first element and no other and set the margin to 0. This moves the users content up flush with the top edge of the container. – 1.21 gigawatts Sep 29 '16 at 08:02
  • @torazaburo I don't want to be nit picky but, ID is short for identity. And div is short for division. I know it doesn't sound right but they are the same. In the past, space was limited so naming things id instead of identity was saving much need space. Now, in some circles it's very important to be verbose. I don't expect others to follow this but it's something I do. If that bothers you don't look at this, http://tron.wikia.com/wiki/Identity_Disc. The nomenclature has carried over from the 1980's. Today it would be ID disc. – 1.21 gigawatts Sep 29 '16 at 08:07
  • @torazaburo would a span be an acceptable substitute? I can post another question that has more of this markup in another post. When I replace `font` with `span` the color, font and other attributes stop working. – 1.21 gigawatts Sep 29 '16 at 08:17
  • The correct term is "ID selector". See https://developer.mozilla.org/en/docs/Web/CSS/ID_selectors. –  Sep 29 '16 at 08:30
  • @1.21gigawatts — When a specification uses an abbreviation as the name of something, then the abbreviation is the correct way to refer to it. – Quentin Sep 29 '16 at 09:26
  • I stand corrected. – 1.21 gigawatts Sep 29 '16 at 09:31

3 Answers3

6

Using a space (blank) between or not is a semantic difference, it controls on what set of elements that additional selector is actually applied on:

  • #myDiv:first-child: no separating blank means you try to filter the set of elements with the id "myDiv". This obviously makes no sense but is semantically valid.

  • #myDiv :first-child: a separating blank means you select out of all elements inside the selected div, so child elements. Note that this does not only match immediate children though, but also children further down the hierarchy.

  • #myDiv > :first-child: a separating "greater than" (arrow) means you select out of all immediate child elements of the selected div. Sp this does not match elements further down the hierarchy.

arkascha
  • 41,620
  • 7
  • 58
  • 90
  • I only want to match the first immediate child element and no descendants. The third solution looks like it will suffice. The first element could be a paragraph, ordered list or unordered list and I don't think any other element type but there is a remote possibility there might be such as a table. – 1.21 gigawatts Sep 29 '16 at 07:55
  • The third option works for me! Marking as solved. – 1.21 gigawatts Sep 29 '16 at 08:15
  • @1.21gigawatts Glad to hear that! Have fun! – arkascha Sep 29 '16 at 08:17
  • See my comment on Andy's answer. It's not obvious to me why #myDiv:first-child doesn't make sense. That IDs have to be unique is irrelevant - the use of :first-child doesn't imply in any way that there are duplicate elements with the same ID. (You also probably meant to say "syntactically valid", because something that makes no sense cannot be "semantically valid".) – BoltClock Sep 29 '16 at 08:17
  • @1.21gigawatts First part: `#myDiv:first-child` does not make sense since an element id _has to be unique_ throughout the page. So that is a precise identification of a specific element and that element is the first child per definition (child of whatever parent element). – arkascha Sep 29 '16 at 08:20
  • @1.21gigawatts Second part: that is an interesting question you raise: can something that makes no sense from a logical point of view still be semantically valid? I'd say yes, sure, completely independent from the syntactical situation. Why not? It is not that the expression `#myDiv:first-child` does not work. We just pointed out that the additional filter selector cannot possibly narrow down the selection, it is without effect _per definition_. Still it is valid, for example it might enhance readability or it might be the product of an automatic rule generation process. – arkascha Sep 29 '16 at 08:23
  • But it can. Compare #myDiv:first-child and #myDiv:nth-child(2). Since IDs must be unique, *and* an element can't be both the first and second child of its parent at the same time, if one of the selectors matches, the other must not. The only situation in which both selectors can (and do, in every browser!) match is in a non-conforming document where both elements have the same ID. Ironically, that's exactly when the additional selector fails to narrow down the selection. – BoltClock Sep 29 '16 at 08:55
  • @BoltClock You are correct in every word you wrote ;-) – arkascha Sep 29 '16 at 08:56
3

#myDiv:first-child take effect only if #myDiv is the first child of his parent.

#myDiv :first-child points to all first children which are descendants of #myDiv.

Example:

#myDiv:first-child {
  padding: 20px;
  background: green;
}
#myDiv :first-child {
  background: red;
}
<div id="myDiv">
  <p>#1</p>
  <p>#2<span>#2-1</span><span>#2-2</span></p>
</div>
Andy Tschiersch
  • 3,716
  • 1
  • 17
  • 24
  • 1
    It doesn't point to "the first child element inside". It points to **all** first children which are descendants. –  Sep 29 '16 at 07:42
  • Minor point, but it's considered better practice not to mark up your posts with **Update** or **EDIT**. Just fix it to say the right thing. No-one is interested in the sequence of changes you made, and if they are, they can look at the edit history themselves. –  Sep 29 '16 at 07:57
  • Why does #myDiv:first-child make no sense? You could potentially have a sibling before #myDiv while keeping #myDiv unique, and #myDiv:first-child would ensure that the element didn't match in that scenario, if the author wanted to match #myDiv only when it came first. That sounds like a perfectly reasonable use case to me. – BoltClock Sep 29 '16 at 08:07
  • Wow BoltClock you are right. I have tested it. I will update my answer according to this. – Andy Tschiersch Sep 29 '16 at 08:21
2

You want to select the first child of an element with a particular ID. To put it a different way, you want to select an element that is the first child, and has as an ancestor an element with a particular ID. The way to do that is

#id :first-child
   ↑              SPACE MEANS ANCESTOR/DESCENDANT RELATIONSHIP

with a space between the two.

In my code I can't get it to work unless I put a space in between the ID and pseudo-class like so:

Right. That's because that's what the space means. It means "descendant". In this case, it means "any descendant of #id which is a first-child". That's what you want.

#id:first-child

does not work, because it does not say what you want. It means "an element with the id of #id, which is also the first child. That's what it means when you run selectors together with no space. That's not what you want. That's why it doesn't work.

I've seen answers suggesting using first child pseudo selector using the following formats:

You can't blindly copy something without understanding what it means. The space between selectors means something very specific. It means the thing on the right of the space is a descendant of the thing on the left. In your case, the paragraph you want to remove margins from is a descendant of the element with the ID. Therefore, you need and want the space.

Part of the reason for your confusion might be that we rarely see pseudo-classes like :first-child all by themselves, without an ID or class or something in front of them, like span:first-child or .class:first-child. So you might wonder why :first-child here has an "extra" space in front of it. Actually, :first-child all by itself is a perfectly selector even with nothing else in front. If you prefer to write #id p:first-child that's OK, of course, but it's not necessary if you already know that the first child is a p. You need to write it as p:first-child only if you want to address elements that are both ps and the first child. The space here, to repeat myself, indicates a descendant relationship between the two different selectors #id and the :first-child.

See the relevant documentation on MDN here. To quote:

A descendant combinator — typically represented by a single space () character in the form of selector₁ selector₂ — combines two selectors such that elements matched by the second selector (selector₂) are selected if they have an ancestor element matching the first selector (selector₁). Selectors that utilize a descendant combinator are called descendant selectors.

  • In my experience, most authors find it surprising that a pseudo-class or pseudo-element can appear by itself, without an accompany type, id or class selector. And when you tell them that a pseudo-class or pseudo-elt can appear by itself in much the same way an id or class selector can, they act like they just had an epiphany. All this because you *rarely* find lone pseudo-classes or pseudo-elts in production CSS (other than :root and ::selection I guess). Not picking on your answer, just always found it interesting how most people react to this information. – BoltClock Sep 29 '16 at 08:44
  • Useful comment, I'll add some stuff to my answer. –  Sep 29 '16 at 08:46
  • I appreciate the detailed answer! Thanks and +1. – 1.21 gigawatts Sep 29 '16 at 09:28