Fix Drupal grid format views template for better group title styling

The Drupal Views grid format displays group titles using the <h3> tag.

The element is not classed so adding CSS is oddly difficult given how well Drupal content is structured.

The real problem, though, is the h3 element is not inside the div it’s associated with. This makes very common styling requirements impossible. For instance, you migth want the values to appear in a column with the h3 group title on top. You cannot do this with the default layout.

The solution is to move the h3 down “one line.”

Solution

This is for Drupal 8. You’ll have to interpolate for Drupal 7, but it won’t be difficult.

First, copy views-view-grid.html.twig from core/modules/views/templates to your theme’s templates folder.

Find the title code about midway:

{% if options.col_class_default %}
  {%
    set col_classes = [
      'views-col',
      options.alignment == 'vertical' ? 'clearfix',
    ]
  %}
{% endif %}
{% if title %}
  <h3>{{ title }}</h3>
{% endif %}
<div{{ attributes.addClass(classes) }}>
  {% if options.alignment == 'horizontal' %}
    {% for row in items %}
      <div{{ row.attributes.addClass(row_classes, options.row_class_default ? 'row-' ~ loop.index) }}>
        {% for column in row.content %}
          <div{{ column.attributes.addClass(col_classes, options.col_class_default ? 'col-' ~ loop.index) }}>
            {{- column.content -}}

These are the title lines:

{% if title %}
  <h3>{{ title }}</h3>
{% endif %}

Move the title lines down below the div that immediately follows it:

{% if options.col_class_default %}
  {%
    set col_classes = [
      'views-col',
      options.alignment == 'vertical' ? 'clearfix',
    ]
  %}
{% endif %}
<div{{ attributes.addClass(classes) }}>
{% if title %}
  <h3 class="views-group-title">{{ title }}</h3>
{% endif %}
  {% if options.alignment == 'horizontal' %}
    {% for row in items %}
      <div{{ row.attributes.addClass(row_classes, options.row_class_default ? 'row-' ~ loop.index) }}>
        {% for column in row.content %}
          <div{{ column.attributes.addClass(col_classes, options.col_class_default ? 'col-' ~ loop.index) }}>
            {{- column.content -}}

Then clear caches so your changes become visible.

Output of your grouped view using the grid format will look like: