logo My Digital Garden

Tailwind custom style

By James Kolean on Jan 22, 2023
Source repository: https://gitlab.com/jameskolean/tailwind-custom-style
Demo: https://jameskolean.gitlab.io/tailwind-custom-style
AstroJavaScriptTailwind
banner

I’m just getting acquainted with Tailwind and generally liking it. I like it as a design system, but I can see why it has its haters. I could easily write two articles, one extolling its virtues and another it’s faults.

I want to address one big complaint: the number of classes and repetition. I will use a ‘timeline’ to illustrate. Taken from Tailwind Elements

<ol class="border-l border-gray-300">
    <li>
        <div class="flex flex-start items-center pt-3">
            <div class="bg-gray-300 w-2 h-2 rounded-full -ml-1 mr-3"></div>
            <p class="text-gray-500 text-sm">01.07.2021</p>
        </div>
        <div class="mt-0.5 ml-4 mb-6">
            <h4 class="text-gray-800 font-semibold text-xl mb-1.5">Title of section 1</h4>
            <p class="text-gray-500 mb-3">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque scelerisque diam non nisi semper, et elementum lorem ornare. Maecenas placerat facilisis mollis. Duis sagittis ligula in sodales vehicula.</p>
        </div>
    </li>
    <li>
        <div class="flex flex-start items-center pt-2">
            <div class="bg-gray-300 w-2 h-2 rounded-full -ml-1 mr-3"></div>
            <p class="text-gray-500 text-sm">13.09.2021</p>
        </div>
        <div class="mt-0.5 ml-4 mb-6">
            <h4 class="text-gray-800 font-semibold text-xl mb-1.5">Title of section 2</h4>
            <p class="text-gray-500 mb-3">Libero expedita explicabo eius fugiat quia aspernatur autem laudantium error architecto recusandae natus sapiente sit nam eaque, consectetur porro molestiae ipsam an deleniti.</p>
        </div>
    </li>
    <li>
        <div class="flex flex-start items-center pt-2">
            <div class="bg-gray-300 w-2 h-2 rounded-full -ml-1 mr-3"></div>
            <p class="text-gray-500 text-sm">25.11.2021</p>
        </div>
        <div class="mt-0.5 ml-4 pb-5">
            <h4 class="text-gray-800 font-semibold text-xl mb-1.5">Title of section 3</h4>
            <p class="text-gray-500 mb-3">Voluptatibus temporibus esse illum eum aspernatur, fugiat suscipit natus! Eum corporis illum nihil officiis tempore. Excepturi illo natus libero sit doloremque, laborum molestias rerum pariatur quam ipsam necessitatibus incidunt, explicabo.</p>
        </div>
    </li>
</ol>

We can simplify this by looping over a data array in a component like this.

---
const data = [
  {
    date: "01.07.2021",
    title: "Title of section 1",
    body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque scelerisque diam non nisi semper, et elementum lorem ornare. Maecenas placerat facilisis mollis. Duis sagittis ligula in sodales vehicula.",
  },
  {
    date: "13.09.2021",
    title: "Title of section 2",
    body: "Libero expedita explicabo eius fugiat quia aspernatur autem laudantium error architecto recusandae natus sapiente sit nam eaque, consectetur porro molestiae ipsam an deleniti.",
  },
  {
    date: "25.11.2021",
    title: "Title of section 3",
    body: "Voluptatibus temporibus esse illum eum aspernatur, fugiat suscipit natus! Eum corporis illum nihil officiis tempore. Excepturi illo natus libero sit doloremque, laborum molestias rerum pariatur quam ipsam necessitatibus incidunt, explicabo.",
  },
];
---

<ol class="border-l border-gray-300">
  {
    data.map((element) => (
      <li>
        <div class="flex flex-start items-center pt-3">
          <div class="bg-gray-300 w-2 h-2 rounded-full -ml-1 mr-3" />
          <p class="text-gray-500 text-sm">{element.date}</p>
        </div>
        <div class="mt-0.5 ml-4 mb-6">
          <h4 class="text-gray-800 font-semibold text-xl mb-1.5">
            {element.title}
          </h4>
          <p class="text-gray-500 mb-3">{element.body}</p>
        </div>
      </li>
    ))
  }
</ol>

Another option is to create a component for each Timeline element like this.

---
const props = Astro.props;
---

<ol class="border-l border-gray-300">
  <li>
    <div class="flex flex-start items-center pt-3">
      <div class="bg-gray-300 w-2 h-2 rounded-full -ml-1 mr-3"></div>
      <p class="text-gray-500 text-sm">{props.date}</p>
    </div>
    <div class="mt-0.5 ml-4 mb-6">
      <h4 class="text-gray-800 font-semibold text-xl mb-1.5">
        {props.title}
      </h4>
      <p class="text-gray-500 mb-3"><slot /></p>
    </div>
  </li>
</ol>

And use it like this.

---
import TimelineElement from "./TimelineElement.astro";
---

<ol class="border-l border-gray-300">
  <TimelineElement date="01.07.2021" title="Title of section 1">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque scelerisque
    diam non nisi semper, et elementum lorem ornare. Maecenas placerat facilisis
    mollis. Duis sagittis ligula in sodales vehicula.
  </TimelineElement>
  <TimelineElement date="13.09.2021" title="Title of section 2">
    Libero expedita explicabo eius fugiat quia aspernatur autem laudantium error
    architecto recusandae natus sapiente sit nam eaque, consectetur porro
    molestiae ipsam an deleniti.
  </TimelineElement>
  <TimelineElement date="25.11.2021" title="Title of section 3">
    Voluptatibus temporibus esse illum eum aspernatur, fugiat suscipit natus!
    Eum corporis illum nihil officiis tempore. Excepturi illo natus libero sit
    doloremque, laborum molestias rerum pariatur quam ipsam necessitatibus
    incidunt, explicabo.
  </TimelineElement>
</ol>

Finally, we can create Custom Styles in Tailwind. We need some Astro config to make this happen.

astro.config.mjs

import {
    defineConfig
} from 'astro/config';

// https://astro.build/config
import tailwind from "@astrojs/tailwind";

// https://astro.build/config
export default defineConfig({
    integrations: [tailwind({
        // Example: Disable injecting a basic `base.css` import on every page.
        // Useful if you need to define and/or import your own custom `base.css`.
        config: {
            applyBaseStyles: false
        }
    })]
});

Add src/styles/global.css and append some Custom Styles

@tailwind base;
@tailwind components;
@tailwind utilities;

@layer components {
    .timeline-disk {
        @apply bg-gray-300 w-2 h-2 rounded-full -ml-1 mr-3;
    }

    .timeline-date {
        @apply text-gray-500 text-sm
    }

    .timeline-title {
        @apply text-gray-800 font-semibold text-xl mb-1.5
    }
}

We can use the styles like this.

---
---

<ol class="border-l border-gray-300">
  <li>

    <div class="flex flex-start items-center pt-3">
      <div class="timeline-disk"></div>
      <p class="timeline-date">01.07.2021</p>
    </div>
    <div class="mt-0.5 ml-4 mb-6">
      <h4 class="timeline-title">Title of section 1</h4>
      <p class="text-gray-500 mb-3">
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque
        scelerisque diam non nisi semper, et elementum lorem ornare. Maecenas
        placerat facilisis mollis. Duis sagittis ligula in sodales vehicula.
      </p>
    </div>

  </li>
  <li>

    <div class="flex flex-start items-center pt-2">
      <div class="timeline-disk"></div>
      <p class="timeline-date">13.09.2021</p>
    </div>
    <div class="mt-0.5 ml-4 mb-6">
      <h4 class="timeline-title">Title of section 2</h4>
      <p class="text-gray-500 mb-3">
        Libero expedita explicabo eius fugiat quia aspernatur autem laudantium
        error architecto recusandae natus sapiente sit nam eaque, consectetur
        porro molestiae ipsam an deleniti.
      </p>
    </div>

  </li>
  <li>

    <div class="flex flex-start items-center pt-2">
      <div class="timeline-disk"></div>
      <p class="timeline-date">25.11.2021</p>
    </div>
    <div class="mt-0.5 ml-4 pb-5">
      <h4 class="timeline-title">Title of section 3</h4>
      <p class="text-gray-500 mb-3">
        Voluptatibus temporibus esse illum eum aspernatur, fugiat suscipit
        natus! Eum corporis illum nihil officiis tempore. Excepturi illo natus
        libero sit doloremque, laborum molestias rerum pariatur quam ipsam
        necessitatibus incidunt, explicabo.
      </p>
    </div>

  </li>
</ol>
© Copyright 2023 Digital Garden cultivated by James Kolean.