Gotcha with HTML Definition Lists (`<dl>`s) and Bootstrap 3's `dl-horizontal` Class

Please note that this post will no longer render examples correctly.

When you use DLs, you have to ensure there is some sort of content in every DD, otherwise the browser will render it out of order."

I discovered that this seems to be some quirkiness with Twitter Bootstrap 3 and its dl-horizontal CSS class (the "issue" does not apply to DLs that do not have this class applied).

I'm unsure if the Bootstrap team expects this behavior or not, but for us it was undesirable. Let me show you what I mean:

In this example, I want to omit my age. But doing it like so is bad:

<dl class="dl-horizontal">
  <dt>Name</dt>
  <dd>Ryan Jafari</dd>
  <dt>Age</dt>
  <dd></dd>
  <dt>Weight</dt>
  <dd>165</dd>
</dl>

...and renders as:

Name
Ryan Jafari
Age
Weight
165

Notice there was no content for "Age", so the "Weight" content gets pushed up. I wonder if I would ever even want to be 165 years old.

To "fix" this, simply add a blank (or some other placeholder) to the empty dd:

<dl class="dl-horizontal">
  <dt>Name</dt>
  <dd>Ryan Jafari</dd>
  <dt>Age</dt>
  <dd>&nbsp;</dd>
  <dt>Weight</dt>
  <dd>165</dd>
</dl>

Voilà:

Name
Ryan Jafari
Age
 
Weight
165

All is well in the world. But one more thing!

If you're doing the Bootstrap + Rails thing like we always are, check out this definition list helper courtesy of Carlos:

def definition_list_pair(model, attr_name, options={})
  label = options[:label] || attr_name.to_s.titleize
  value = options[:value] || model.send(attr_name)
  value = '-' unless strip_tags(value).blank?
  content_tag(:dt, label) + content_tag(:dd, value)
end

And use it in your views like so:

<dl class='dl-horizontal'>
  <%= definition_list_pair tour, :published? %>
  <%= definition_list_pair tour, :price, label: 'Base Price' %>
  <%= definition_list_pair tour, :active, value: 'TODO' %>
  <%= definition_list_pair tour, :description %>
</dl>

Not bad, right?