CLS problem with webform cards

Created on 17 February 2025, about 2 months ago

When using webform card there is a CLS (cumulative layout shift) problem.

The css uses the html class of the body to hide each card. It then uses the webform-card--active class to show the active card, but that class, and the body.html, is set with javascript.

As a consequence there is a layout shift until the javascript has loaded the html class and then the webform-card-active class.

I understand that this is done to support the display of the cards without javascript, but it is hindering the display of the page where the webform is inserted.

As I don't know if this is by design and can't be changed, I put here the steps so that whoever has the same problem can avoid it without modifying the module:

Overwrite in your theme the css of webform_cards.css with this content. For the example i've put the file in my theme in libraries/forms/webform/webform_cards.css

/**
 * @file
 * Webform cards styles.
 */

.webform-card {
  border: 1px solid #ccc;
  padding: 20px;
  margin-bottom: 1em;
}

.webform-card,
.webform-card[style*="display: block"] {
  display: none !important;
}

.webform-card.webform-card--active,
html.js .webform-card.webform-card--error,
html.js .webform-card.webform-card--active[style*="display: block"],
html.js .webform-card.webform-card--error[style*="display: block"] {
  display: block !important;
}

html.js .webform-cards .form-actions {
}

.webform-preview .webform-card-edit {
  display: none;
}

.webform-wizard-pages-links {
  display: none;
}

/**
 * Toggle.
 */
.webform-cards-toggle-wrapper {
  margin-top: 1em;
  text-align: right; /* LTR */
}

[dir="rtl"] .webform-cards-toggle-wrapper {
  text-align: left;
}

.webform-cards-toggle {
  margin-top: 0;
  background: transparent;
  border: 0;
  padding: 0;
  color: #337ab7;
  cursor: pointer;
  font-size: 1em;
  text-decoration: none;
}

.webform-cards-toggle:hover,
.webform-cards-togglelink:focus {
  text-decoration: underline;
}

html.js form.webform-cards-toggle-show .webform-card,
html.js form.webform-cards-toggle-show .webform-card[style*="display: block"] {
  display: block !important;
}

html.js form.webform-cards-toggle-show .webform-card[style*="display: none"] {
  display: none !important;
}

html.js form.webform-cards-toggle-show .webform-progress {
  display: none;
}

Add to the .info of your theme:

libraries-override:
  webform_cards/webform_cards:
    css:
      component:
        css/webform_cards.css: libraries/forms/webform/webform_cards.css

In a form_alter add the webform-card-active class to the first card.

/**
   * hook_form_alter
**/
function YOUR_MODULE_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  if(strpos($form_id, 'YOUR_WEBFORM_ID') === 0) {
      $form["elements"]["step_1"]['#attributes']['class'][] = 'webform-card--active';
  }
}
🐛 Bug report
Status

Active

Version

6.3

Component

Code

Created by

🇪🇸Spain Carlitus

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

Comments & Activities

Production build 0.71.5 2024