Trevor Dixon
Trevor Dixon

Reputation: 24382

CSS to add commas between <dd>s

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.

Upvotes: 2

Views: 1740

Answers (3)

Bjorn
Bjorn

Reputation: 46

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>

Upvotes: 0

Rick Hitchcock
Rick Hitchcock

Reputation: 35670

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>

Upvotes: 0

Josh Crozier
Josh Crozier

Reputation: 241138

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>

Upvotes: 3

Related Questions