uuid: - value: 8bcfc61c-0285-4034-ac7b-a3ba7559fba2 langcode: - value: en type: - target_id: daily_email target_type: node_type target_uuid: 8bde1f2f-eef9-4f2d-ae9c-96921f8193d7 revision_timestamp: - value: '2025-05-11T09:00:46+00:00' revision_uid: - target_type: user target_uuid: b8966985-d4b2-42a7-a319-2e94ccfbb849 revision_log: { } status: - value: true uid: - target_type: user target_uuid: b8966985-d4b2-42a7-a319-2e94ccfbb849 title: - value: | Tailwind: why I prefer to extract HTML components created: - value: '2023-02-20T00:00:00+00:00' changed: - value: '2025-05-11T09:00:46+00:00' promote: - value: false sticky: - value: false default_langcode: - value: true revision_translation_affected: - value: true path: - alias: /daily/2023/02/20/tailwind-why-i-prefer-to-extract-html-components langcode: en body: - value: |

Tailwind offers the @apply directive that you can use to extract components in your CSS by applying the styles the classes would have added.

For example:

/* Input */

      .btn {
        @apply inline-block rounded-3xl bg-blue-500 px-8 py-3 text-lg text-white hover:bg-blue-800 focus:bg-blue-800;
      }

      /* Output */

      .btn {
        --tw-bg-opacity: 1;
        --tw-text-opacity: 1;
        background-color: rgb(59 130 246 / var(--tw-bg-opacity));
        border-radius: 1.5rem;
        color: rgb(255 255 255 / var(--tw-text-opacity));
        display: inline-block;
        font-size: 1.125rem;
        line-height: 1.75rem;
        padding-bottom: 0.75rem;
        padding-left: 2rem;
        padding-right: 2rem;
        padding-top: 0.75rem;
      }

      .btn:hover {
        --tw-bg-opacity: 1;
        background-color: rgb(30 64 175 / var(--tw-bg-opacity));
      }

      .btn:focus {
        --tw-bg-opacity: 1;
        background-color: rgb(30 64 175 / var(--tw-bg-opacity));
      }
      

Whilst this works and reduced duplication, I prefer to handle this within my HTML instead.

All templating engines I've used have ways to loop over or map through items and including separate files such as separate partials or different components.

The main benefit of this is that you get the HTML structure of the component and not just the styling. If you extract a .btn component, it may depend on a span or other element within it to display correctly but as this isn't obvious, it may be missed when writing an implementation of it in HTML - this can't happen when working inside a loop or importing a canonical version.

Also, by working just in the HTML markup, we continue to get the lower cognitive load and speed benefits that we're used to when styling with utility classes rather than switching between multiple files.

format: full_html processed: |

Tailwind offers the @apply directive that you can use to extract components in your CSS by applying the styles the classes would have added.

For example:

/* Input */

      .btn {
        @apply inline-block rounded-3xl bg-blue-500 px-8 py-3 text-lg text-white hover:bg-blue-800 focus:bg-blue-800;
      }

      /* Output */

      .btn {
        --tw-bg-opacity: 1;
        --tw-text-opacity: 1;
        background-color: rgb(59 130 246 / var(--tw-bg-opacity));
        border-radius: 1.5rem;
        color: rgb(255 255 255 / var(--tw-text-opacity));
        display: inline-block;
        font-size: 1.125rem;
        line-height: 1.75rem;
        padding-bottom: 0.75rem;
        padding-left: 2rem;
        padding-right: 2rem;
        padding-top: 0.75rem;
      }

      .btn:hover {
        --tw-bg-opacity: 1;
        background-color: rgb(30 64 175 / var(--tw-bg-opacity));
      }

      .btn:focus {
        --tw-bg-opacity: 1;
        background-color: rgb(30 64 175 / var(--tw-bg-opacity));
      }
      

Whilst this works and reduced duplication, I prefer to handle this within my HTML instead.

All templating engines I've used have ways to loop over or map through items and including separate files such as separate partials or different components.

The main benefit of this is that you get the HTML structure of the component and not just the styling. If you extract a .btn component, it may depend on a span or other element within it to display correctly but as this isn't obvious, it may be missed when writing an implementation of it in HTML - this can't happen when working inside a loop or importing a canonical version.

Also, by working just in the HTML markup, we continue to get the lower cognitive load and speed benefits that we're used to when styling with utility classes rather than switching between multiple files.

summary: null field_daily_email_cta: { }