2

Best attempt so far

dd { display: inline; margin: 0; }
dd + dd::before {
  content: ', ';
}
<dl>
  <dt>One</dt>
  <dd>one</dd>
  <dd>two</dd>
  <dd>three</dd>

  <dt>Two</dt>
  <dd>one</dd>
  <dd>two</dd>
  <dd>three</dd>
</dl>

I'd like to add commas between the <dd> elements using CSS pseudo-elements. The only problem with the above attempt is that there's a space before each comma.

When I do this with <li>s, I can use ::after pseudo-elements and target li:last-of-type to remove the comma from the last item, but I can't figure out a way to target the last <dd> in my example. I think the proposed has selector could help (like dd:has(+ dd)). Is there any workaround in CSS3?

Or is there a good way to get rid of the space? If I have to, I'll use a negative margin to pull the comma back toward the preceding word.

Trevor Dixon
  • 17,772
  • 8
  • 66
  • 100
  • To fix the whitespace: [How to remove the space between inline-block elements?](http://stackoverflow.com/q/5078239/1529630). – Oriol Mar 20 '15 at 22:56

3 Answers3

3

The space that you are seeing between the elements is determined by the parent element's font-size. Inline elements respect the whitespace in the markup.

One way to remove this would be to set the parent element's font-size to 0, and then reset the children element's font-size. See this answer for alternative approaches.

dl {
  font-size: 0;
}
dd, dt {
  font-size: 16px;
}
dd {
  display: inline;
  margin: 0;
}
dd + dd::before {
  content: ', ';
}
<dl>
  <dt>One</dt>
  <dd>one</dd>
  <dd>two</dd>
  <dd>three</dd>

  <dt>Two</dt>
  <dd>one</dd>
  <dd>two</dd>
  <dd>three</dd>
</dl>
Community
  • 1
  • 1
Josh Crozier
  • 202,159
  • 50
  • 343
  • 273
  • 1
    You could also remove the space between the HTML elements like this: `
    `. It's because of the element have a (default) `display` value of `inline` or `inline-block` that it adds these spaces.
    – mnsth Mar 20 '15 at 22:43
  • @mnsth Yep--that's why I linked to this other answer of mine - http://stackoverflow.com/questions/19038799/why-is-there-an-unexplainable-gap-between-these-inline-block-div-elements/19038859#19038859 – Josh Crozier Mar 20 '15 at 22:44
0

You could apply a negative left margin to the pseudo-element in ems. -0.2em seems to work well:

dd, dt {
  font: 16px verdana;
}

dd {
  display: inline;
  margin: 0;
}

dd+dd::before {
  content: ', ';
  margin-left: -0.2em;
}
<dl>
  <dt>One</dt>
  <dd>one</dd>
  <dd>two</dd>
  <dd>three</dd>

  <dt>Two</dt>
  <dd>one</dd>
  <dd>two</dd>
  <dd>three</dd>
</dl>
Rick Hitchcock
  • 33,093
  • 3
  • 40
  • 70
0

Having the ', ' before an element seems wrong to me. Imho it should be after the element, but of course not on the last element.

Next to that, first the space is removed and added later again which seems a bit strange to me.

How about leaving the space as is and simply add a comma after the element using ::after.

The problem you run into is is that the last element still contains a comma, but you have not trouble with a , floating somewhere and as a bonus, it is at the place it should be.

So basically you don't want the last element to match. Luckily we have something we can use for this. By using :not(:last-child) you target all elements except the selector used inside the parentheses.

dd, dt {
  font: 16px verdana;
}

dd {
  display: inline;
  margin: 0;
}

dd:not(:last-of-type)::after {
  content: ',';  
}
<dl>
  <div class="group">
    <dt>One</dt>
    <dd>one</dd>
    <dd>two</dd>
    <dd>three</dd>
  </div>

  <div class="group">
    <dt>Two</dt>
    <dd>one</dd>
    <dd>two</dd>
    <dd>three</dd>
  </div>
</dl>
Bjorn
  • 11
  • 3
  • :last-child doesn't work here. Notice the comma after the first "three". Need some kind of sibling selector to work. – Trevor Dixon Jan 07 '21 at 11:36
  • Yes, you are right. Strange that I missed that. The easiest solution would be to to group them. I've changed my code to reflect that. – Bjorn Jan 08 '21 at 12:41