Browsers add space to output because of extra space in templates.

Created on 23 September 2024, 7 months ago

Problem/Motivation

Browsers are adding unintended spaces in the rendered output due to extra spaces or newlines in the templates/field-group-html-element.html.twig file of the Field Group module. This is problematic in cases where compact rendering is important, such as inline, collapsible, or nested field groups. These unwanted spaces are introduced because the HTML tags in the template are not rendered tightly together, and browsers interpret the extra spaces or newlines as visible gaps.

Steps to reproduce

  • Create a field group using the Field Group module with settings like collapsible or inline display.
  • Inspect the rendered HTML using your browserโ€™s developer tools.
  • Notice that extra spaces or gaps appear between HTML tags, which should be rendered tightly.

Proposed resolution

Apply the Twig spaceless filter to the templates/field-group-html-element.html.twig template to remove extra spaces and newlines between HTML tags, ensuring the output is more compact and correctly rendered without unintended gaps.

Example of the updated template:

{% apply spaceless %}
<{{ wrapper_element }} {{ attributes }}>
  {% if title %}
    <{{ title_element }}{{ title_attributes }}>{{ title }}</{{ title_element }}>
  {% endif %}
  {% if collapsible %}
    <div class="field-group-wrapper">
  {% endif %}
  {{ children }}
  {% if collapsible %}
    </div>
  {% endif %}
</{{ wrapper_element }}>
{% endapply %}

Remaining tasks

  • Review the changes in the template to ensure no issues arise from removing extra spaces.
  • Test with different field group configurations (collapsible, inline, nested) to confirm expected behavior.

User interface changes

None

API changes

If your theme or module fixes this kind of output with CSS negative margin or the like, you will see overlapping fields after this change is applied.

Data model changes

None

๐Ÿ› Bug report
Status

Active

Version

4.0

Component

Code

Created by

๐Ÿ‡บ๐Ÿ‡ธUnited States trackleft2 Tucson, AZ ๐Ÿ‡บ๐Ÿ‡ธ

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @trackleft2
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States trackleft2 Tucson, AZ ๐Ÿ‡บ๐Ÿ‡ธ
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States trackleft2 Tucson, AZ ๐Ÿ‡บ๐Ÿ‡ธ
  • ๐Ÿ‡ฎ๐Ÿ‡ณIndia Tirupati_Singh

    Hi @trackleft2, I tried replicating the issue but the issue didn't replicate. I didn't encounter the extra spaces, new lines issues in the HTML tag for the field group using the collapsible option. Could you please provide more details about the issue and screenshots related to the issue? I've attached the screenshots of the configuration that I've used for the field groups.
    Tested on Drupal 10.3.2 and Field group 4.0.0-alpha1.

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States trackleft2 Tucson, AZ ๐Ÿ‡บ๐Ÿ‡ธ

    Yes, If you add new field group and place two fields inside of it, you'll see a space between them. In this case there is a space between "Anders And" and a comma ","

  • ๐Ÿ‡ฎ๐Ÿ‡ณIndia Tirupati_Singh

    I've implemented the same structure for field_group as shown in the attached screenshots but I didn't encounter the spacing issue while using the module for group type HTML Element with configuration set to inline. I've also used the smart_title module for the name field. The space between the two fields is showing only when the space has been provided in the content. Could you share the screenshot of your node edit page and field configuration for Person name suffix with leading comma. I've attached the screenshots of with and without spaces along with configurations that I've used for your reference. Please have a look into it.

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States trackleft2 Tucson, AZ ๐Ÿ‡บ๐Ÿ‡ธ

    I am using a pseudo field like this:

    /**
     * Implements hook_entity_extra_field_info().
     */
    function my_module_entity_extra_field_info() {
      $extra = [];
    
      // Check to see if our content type exists.
      $bundle = NodeType::load('my_node_type');
      if ($bundle) {
        // Comma pseudo field.
        $extra['node'][$bundle->id()]['display']['suffix'] = [
          'label' => t('Name suffix with leading comma.'),
          'description' => "This is a pseudo field from my_module.",
          'weight' => 50,
          'visible' => FALSE,
        ];
      }
    
      return $extra;
    }
    
    /**
     * Implements hook_ENTITY_TYPE_view().
     */
    function my_module_node_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
      if ($entity instanceof FieldableEntityInterface) {
        if ($entity->hasField('field_suffix')) {
          $suffix_field = $entity->get('field_suffix');
          $items = [];
          foreach ($suffix_field as $suffix_item) {
            $item_value = $suffix_item->getValue();
            $items[] = [
              '#markup' => $item_value['value'] ?? '',
              '#wrapper_attributes' => ['class' => ['list-inline-item']],
            ];
          }
          $build['suffix'] = [
            '#theme' => 'item_list',
            '#items' => $items,
            '#context' => ['list_style' => 'comma-list'],
            '#attributes' => ['class' => ['list-inline']],
            '#wrapper_attributes' => ['class' => ['inline', 'with-leading-comma']],
            '#theme_wrappers' => [],
          ];
        }
      }
    
    
  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany Anybody Porta Westfalica

    Thanks, happy to review MR's fo a clean fix.

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States trackleft2 Tucson, AZ ๐Ÿ‡บ๐Ÿ‡ธ

    Looks like Drupal will be adding a spaceless replacement in ๐Ÿ“Œ Twig Filter "spaceless" is deprecated Active .

    I've been testing adding the apply spaceless filter in the https://git.drupalcode.org/project/field_group/-/blob/4.x/templates/fiel... file, however I've found that some content editors have been relying on the space added between elements, and removing it causes unintended display changes.

    My new approach is to copy the field-group-html-element.html.twig file into my themes as element specific templates like...
    field-group-html-element--h1.html.twig and then wrapping the children variable in the spaceless filter like:

    {#
    /**
     * @file
     * Default theme implementation for a fieldgroup html element.
     *
     * Available variables:
     * - title: Title of the group.
     * - title_element: Element to wrap the title.
     * - children: The children of the group.
     * - wrapper_element: The html element to use
     * - attributes: A list of HTML attributes for the group wrapper.
     *
     * @see template_preprocess_field_group_html_element()
     *
     * @ingroup themeable
     */
    #}
    <{{ wrapper_element }} {{ attributes }}>
    {% if title %}
      <{{ title_element }}{{ title_attributes }}>{{ title }}</{{ title_element }}>
    {% endif %}
    {% if collapsible %}
      <div class="field-group-wrapper">
    {% endif %}
    {% apply spaceless %}{{children}}{% endapply %}
    {% if collapsible %}
      </div>
    {% endif %}
    </{{ wrapper_element }}>
    
    
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States trackleft2 Tucson, AZ ๐Ÿ‡บ๐Ÿ‡ธ

    New idea! Add option to field_group configuration for applying the spaceless filter to the template, and then turn the filter on if that option is selected.

    Maybe something like this:

    $form['field_group']['spaceless'] = [
      '#type' => 'checkbox',
      '#title' => t('Enable Spaceless Filter'),
      '#description' => t('Select this option to remove unnecessary whitespace between HTML elements in this field group. While this can lead to cleaner HTML output and potentially enhance rendering performance, be aware that it may affect the visual spacing of elements in some themes or contexts. Use with caution to ensure it meets your design needs.'),
    ];
    
  • Assigned to Tirupati_Singh
  • Pipeline finished with Failed
    14 days ago
    Total: 334s
    #470182
  • ๐Ÿ‡ฎ๐Ÿ‡ณIndia Tirupati_Singh

    Hi @trackleft2, I've replicated the issue as per the comment #8 ๐Ÿ› Browsers add space to output because of extra space in templates. Active and confirm that the issue persists. The rendered element is getting some extra spaces when the "HTML Elements" is selected as formatter for the field group. I've tested the issue after applying the spaceless filter, and on applying it, the additional space got removed.

    As suggested by @trackleft2, it would be better to provide an option to users to enable/disable the filter as per their need. Hence, I've added a new configuration option, named Enable Spaceless Filter for the field group when the "HTML Element" option is selected. When "Enable Spaceless Filter" is checked, then the elements will be rendered through template applied with spaceless filter, and if not checked, then it will be rendered without spaceless filter applied.

    I'm attaching screenshots of the before and after fixes of the issue for reference. Please review the MR changes.

    Thanks!

  • Pipeline finished with Failed
    14 days ago
    Total: 437s
    #470230
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States trackleft2 Tucson, AZ ๐Ÿ‡บ๐Ÿ‡ธ

    Overall I like what you've done here, thank you!
    I've added some suggestions to the wording of the setting that you can decide whether you like or not.

    I've marked this as RTBC, since my code suggestions are optional.

    I do wonder if people will be confused by this new strange option that doesn't really have an explanation.

    Essentially, the "spaceless" filter exists because browsers interpret the space between HTML elements.

    Example:

    This

    <div>test1</div>
    <div>test2</div>
    

    behaves differently from

    <div>test1</div><div>test2</div>
    

    If a developer writes a template for code readability, they risk adding in browser interpreted breaking space.

    This is in essence a coding standards artifact.

  • Pipeline finished with Failed
    14 days ago
    Total: 466s
    #470858
  • ๐Ÿ‡ฎ๐Ÿ‡ณIndia Tirupati_Singh

    Hi @trackleft2, I've updated the form's new element name from "Enable Spaceless Filter" to "Remove whitespace between HTML tags". I think the new form element label will be easy for a normal user to understand. For more clarification, the user will have to go through the description provided for the element.

    I've also updated a conditional check to the new element so as to show "Remove whitespace between HTML tags" only when configuring the field group for a node view page. Previously, the "Remove whitespace between HTML tags" option was available for both "Manage Form Display" and "Manage Display" although it was only intended for the node view to filter extra space when visiting the actual page content. However, it was also available for form display, which was not required. After the new changes, the "Remove whitespace between HTML tags" will only be available for "Manage Display" form when adding/updating a field group.

    Since I've updated the code logic, I'm moving issue status back to Needs Review state from RTBC. I'm attaching the screenshots of the after fixes for reference. Please review the MR new changes.

    Thanks!

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States trackleft2 Tucson, AZ ๐Ÿ‡บ๐Ÿ‡ธ

    Just realized we need to set the new configuration option by adding something to https://git.drupalcode.org/project/field_group/-/blob/4.x/field_group.po...

    Maybe something like

    /**
     * Set default 'remove_whitespace' setting for HtmlElement formatters.
     */
    function field_group_post_update_add_remove_whitespace_setting(array &$sandbox = NULL): void {
      $entity_type_manager = \Drupal::entityTypeManager();
      $storage = $entity_type_manager->getStorage('field_group');
    
      if (!isset($sandbox['group_ids'])) {
        $group_ids = $storage->getQuery()
          ->accessCheck(FALSE)
          ->execute();
        $sandbox['group_ids'] = array_values($group_ids);
        $sandbox['current'] = 0;
        $sandbox['total'] = count($sandbox['group_ids']);
      }
    
      $limit = 25;
      $group_ids_chunk = array_slice($sandbox['group_ids'], $sandbox['current'], $limit);
      $sandbox['current'] += count($group_ids_chunk);
    
      /** @var \Drupal\field_group\Entity\FieldGroup[] $groups */
      $groups = $storage->loadMultiple($group_ids_chunk);
      foreach ($groups as $group) {
        $settings = $group->get('settings');
        if (($settings['formatter'] ?? '') === 'html_element' && !isset($settings['remove_whitespace'])) {
          $settings['remove_whitespace'] = FALSE;
          $group->set('settings', $settings);
          $group->save();
        }
      }
    
      $sandbox['#finished'] = ($sandbox['current'] >= $sandbox['total']);
    }
    
    
Production build 0.71.5 2024