How to turn field_label into an h1 tag I have a content type containing many fields. I want to attach H1, h2, h3, tags to the field_labels of the fields.


Is this possible?
How can I do this?


I am relatively new to Drupal. Thanks.
Yep! This is entirely possible and a very common use case.

If you check out the field.html.twig file in the classy base theme of core, it has the following contents:

{#
/**
 * @file
 * Theme override for a field.
 *
 * To override output, copy the "field.html.twig" from the templates directory
 * to your theme's directory and customize it, just like customizing other
 * Drupal templates such as page.html.twig or node.html.twig.
 *
 * Instead of overriding the theming for all fields, you can also just override
 * theming for a subset of fields using
 * @link themeable Theme hook suggestions. @endlink For example,
 * here are some theme hook suggestions that can be used for a field_foo field
 * on an article node type:
 * - field--node--field-foo--article.html.twig
 * - field--node--field-foo.html.twig
 * - field--node--article.html.twig
 * - field--field-foo.html.twig
 * - field--text-with-summary.html.twig
 * - field.html.twig
 *
 * Available variables:
 * - attributes: HTML attributes for the containing element.
 * - label_hidden: Whether to show the field label or not.
 * - title_attributes: HTML attributes for the title.
 * - label: The label for the field.
 * - multiple: TRUE if a field can contain multiple items.
 * - items: List of all the field items. Each item contains:
 *   - attributes: List of HTML attributes for each item.
 *   - content: The field item's content.
 * - entity_type: The entity type to which the field belongs.
 * - field_name: The name of the field.
 * - field_type: The type of the field.
 * - label_display: The display settings for the label.
 *
 *
 * @see template_preprocess_field()
 */
#}
{%
  set classes = [
    'field',
    'field--name-' ~ field_name|clean_class,
    'field--type-' ~ field_type|clean_class,
    'field--label-' ~ label_display,
  ]
%}
{%
  set title_classes = [
    'field__label',
    label_display == 'visually_hidden' ? 'visually-hidden',
  ]
%}

{% if label_hidden %}
  {% if multiple %}
    &lt;div{{ attributes.addClass(classes, 'field__items') }}&gt;
      {% for item in items %}
        &lt;div{{ item.attributes.addClass('field__item') }}&gt;{{ item.content }}&lt;/div&gt;
      {% endfor %}
    &lt;/div&gt;
  {% else %}
    {% for item in items %}
      &lt;div{{ attributes.addClass(classes, 'field__item') }}&gt;{{ item.content }}&lt;/div&gt;
    {% endfor %}
  {% endif %}
{% else %}
  &lt;div{{ attributes.addClass(classes) }}&gt;
    &lt;div{{ title_attributes.addClass(title_classes) }}&gt;{{ label }}&lt;/div&gt;
    {% if multiple %}
      &lt;div class="field__items"&gt;
    {% endif %}
    {% for item in items %}
      &lt;div{{ item.attributes.addClass('field__item') }}&gt;{{ item.content }}&lt;/div&gt;
    {% endfor %}
    {% if multiple %}
      &lt;/div&gt;
    {% endif %}
  &lt;/div&gt;
{% endif %}


Most themes extend classy as a base. If not, they extend stable by default. Both have a field.html.twig file in their theme folder. Every field in your site will render with this template by default, unless a more specific template is provided by creating a new file and giving it a specific theme name suggestions, which are mentioned in the comments of the file above.

If you copy this file to your theme, you can then override this markup for your theme.

If you enable twig debugging, it will inject template suggestion names into the source as you view the page. These will allow more granular control over field level markup and help figure out what filenames and their order of specificity are in order to override template output.

Let's say you have a field called Company. For this field, you want the label to be an H3. One of the possible template suggestions would be field--field-company.html.twig. If you create that file and place it in your theme, you can do:

{#
/**
 * @file
 * Theme override the Company field.
 *
 * Available variables:
 * - attributes: HTML attributes for the containing element.
 * - label_hidden: Whether to show the field label or not.
 * - title_attributes: HTML attributes for the title.
 * - label: The label for the field.
 * - multiple: TRUE if a field can contain multiple items.
 * - items: List of all the field items. Each item contains:
 *   - attributes: List of HTML attributes for each item.
 *   - content: The field item's content.
 * - entity_type: The entity type to which the field belongs.
 * - field_name: The name of the field.
 * - field_type: The type of the field.
 * - label_display: The display settings for the label.
 *
 *
 * @see template_preprocess_field()
 */
#}
{%
  set classes = [
    'field',
    'field--name-' ~ field_name|clean_class,
    'field--type-' ~ field_type|clean_class,
    'field--label-' ~ label_display,
  ]
%}
{%
  set title_classes = [
    'field__label',
    label_display == 'visually_hidden' ? 'visually-hidden',
  ]
%}

{% if label_hidden %}
  {% if multiple %}
    &lt;div{{ attributes.addClass(classes, 'field__items') }}&gt;
      {% for item in items %}
        &lt;div{{ item.attributes.addClass('field__item') }}&gt;{{ item.content }}&lt;/div&gt;
      {% endfor %}
    &lt;/div&gt;
  {% else %}
    {% for item in items %}
      &lt;div{{ attributes.addClass(classes, 'field__item') }}&gt;{{ item.content }}&lt;/div&gt;
    {% endfor %}
  {% endif %}
{% else %}
  &lt;div{{ attributes.addClass(classes) }}&gt;
    &lt;h3{{ title_attributes.addClass(title_classes) }}&gt;{{ label }}&lt;/h3&gt;
    {% if multiple %}
      &lt;div class="field__items"&gt;
    {% endif %}
    {% for item in items %}
      &lt;div{{ item.attributes.addClass('field__item') }}&gt;{{ item.content }}&lt;/div&gt;
    {% endfor %}
    {% if multiple %}
      &lt;/div&gt;
    {% endif %}
  &lt;/div&gt;
{% endif %}


Note where I changed the label div to an h3. The top part of the if statement is only if you set the label to Hidden in the Display settings of the content type.

Suppose you always want a label to display for Company, you can simplify the template further:

{#
/**
 * @file
 * Theme override the Company field.
 *
 * Available variables:
 * - attributes: HTML attributes for the containing element.
 * - label_hidden: Whether to show the field label or not.
 * - title_attributes: HTML attributes for the title.
 * - label: The label for the field.
 * - multiple: TRUE if a field can contain multiple items.
 * - items: List of all the field items. Each item contains:
 *   - attributes: List of HTML attributes for each item.
 *   - content: The field item's content.
 * - entity_type: The entity type to which the field belongs.
 * - field_name: The name of the field.
 * - field_type: The type of the field.
 * - label_display: The display settings for the label.
 *
 *
 * @see template_preprocess_field()
 */
#}
{%
  set classes = [
    'field',
    'field--name-' ~ field_name|clean_class,
    'field--type-' ~ field_type|clean_class,
    'field--label-' ~ label_display,
  ]
%}
{%
  set title_classes = [
    'field__label',
    label_display == 'visually_hidden' ? 'visually-hidden',
  ]
%}

 &lt;div{{ attributes.addClass(classes) }}&gt;
   &lt;h3{{ title_attributes.addClass(title_classes) }}&gt;{{ label }}&lt;/h3&gt;

   {% if multiple %}
     &lt;div class="field__items"&gt;
   {% endif %}
   {% for item in items %}
     &lt;div{{ item.attributes.addClass('field__item') }}&gt;{{ item.content }}&lt;/div&gt;
   {% endfor %}
   {% if multiple %}
     &lt;/div&gt;
   {% endif %}
 &lt;/div&gt;


After clearing the site cache, Drupal should pick up on this new template file, and render any instance of the Company field with it, getting your new label markup. But note, now that you do this change, setting the Company label to hidden in the future will have no effect! We removed the logic - just to illustrate.

That's the nuts and bolts of whats going on and how you can adapt and theme field output, or nodes, taxonomy, user, paragraphs, views, etc.

If you have a lot of fields and this seems overwhelming right now, there is a module called Display Suite that places a lot of this into the admin UI on the field display settings form. If you are new to Drupal 8, twig, etc - Display Suite is a fine starting point because it will accomplish the same thing, just without much, if any, coding. 

For Display Suite check the documentation here about fields and labels.

Furthermore, I recommend Drupalize.me's excellent series on theming in Drupal 8. It will help accelerate your knowledge of theming much faster.