No Time Dad

A blog about web development written by a busy dad

Easy Placeholder Elements with Tailwind

From time to time I need elements whose only purpose is to look nice and take up space on a page. Usually I need these placeholder elements when making an async request or doing something fancy in the background and I want to show something rather than nothing.

A few frontend libraries have placeholder elements built in, but I thought it would be fun to build my own. It also gives me more flexibility and allows my placeholder elements to be unique. And I figured while I’m at it, I might as well use Tailwind to make them.

I’ll be using circles for avatar placeholders and I’m curious if using svg and circle elements would be better than using a div element with border-radius: 100% and padding: 3rem (or whatever rem value). I’ve typically always done the latter. But that, of course, doesn’t mean it’s right. It’s just what I’m used to doing.

I think the main issue with using the circle element is that I have to hardcode some of the circle attributes, including the size, in the element itself. I also lose the ability to use Tailwind’s utility classes, including the color palette I like so much. I wouldn’t be able to do fill="bg-blue-500" or similar.

<svg>
  <circle cx="50" cy="50" r="50" fill="lightblue" />
</svg>

So, maybe svg and circle aren’t a great fit for me for these placeholder elements. I can achieve mostly the same result using a div, though. This method also allows me to utilize Tailwind as much as I need to.

<div class="rounded-full h-24 w-24 bg-blue-200"></div>

Building placeholder elements

That’s probably enough about circles. The placeholder element itself will be styled like a card, using Tailwind’s shadow utility class to give the element it’s shape. I’ll also use flexbox to align the elements in the placeholder.

This first version will consist of an avatar placeholder and two rectangles that would represent a persons name and title. It starts with a parent div where flexbox is initialized via Tailwind’s flex utility class, as well as shadow-md and rounded-md to define the card outline. It also uses the div circle from above. The rectangles sit inside a div that uses Tailwind’s flex-1 which is equivalent to flex: 1 1 0% to ensure the rectangles fill all of the available space.

<div class="flex items-center shadow-md rounded-md bg-white p-4">
  <div class="rounded-full h-24 w-24 bg-blue-200"></div>
  <div class=" flex-1 ml-4">
    <div class="bg-gray-200 p-4 rounded-md mb-2"></div>
    <div class="bg-gray-200 p-4 rounded-md"></div>
  </div>
</div>

Here’s another version that is more complex. Same general idea as the one before, but this time the card has header, content, and footer sections. Again I’m using flexbox all over the place.

I do like using softer colors for these placeholder elements because they’re really not meant to draw in the user’s attention too much. They just need to fill in some spaces that would otherwise be blank.

<div class="shadow-md rounded-md bg-white p-4">
  <div class="border-b border-gray-200">
    <div class="flex items-center py-2">
      <div class="rounded-full h-20 w-20 bg-blue-200"></div>
      <div class="flex-1 ml-4">
        <div class="bg-gray-200 p-2 rounded-md mb-2"></div>
        <div class="bg-gray-200 p-2 rounded-md"></div>
      </div>
    </div>
  </div>
  <div class="space-y-2 py-4">
    <div class="bg-gray-200 p-2 rounded-md"></div>
    <div class="bg-gray-200 p-2 rounded-md"></div>
    <div class="bg-gray-200 p-2 rounded-md"></div>
  </div>
  <div class="flex justify-between">
    <div class="rounded-md w-20 h-14 bg-indigo-200"></div>
    <div class="rounded-md w-20 h-14 bg-green-200"></div>
  </div>
</div>

So, here is one last version that is much simpler than the others. It’s basically a rectangle and a pill in a card. This particular placeholder looks really nice when it’s stacked on different color version of itself.

<div class="shadow-md rounded-md bg-white p-4">
  <div class="flex flex-row items-stretch">
    <div class="bg-gray-200 p-4 rounded-md w-3/4"></div>
    <div class="bg-red-200 rounded-2xl ml-2 flex-1"></div>
  </div>
</div>

And here is the stacked version. This version just adds a wrapper div that used Tailwind’s space-y-3 to add spacing between the elements.

<div class="space-y-3">
  <div class="shadow-md rounded-md bg-white p-4">
    <div class="flex flex-row items-stretch">
      <div class="bg-gray-200 p-4 rounded-md w-3/4"></div>
      <div class="bg-red-200 rounded-2xl ml-2 flex-1"></div>
    </div>
  </div>
  <div class="shadow-md rounded-md bg-white p-4">
    <div class="flex flex-row items-stretch">
      <div class="bg-gray-200 p-4 rounded-md w-3/4"></div>
      <div class="bg-blue-200 rounded-2xl ml-2 flex-1"></div>
    </div>
  </div>
  <div class="shadow-md rounded-md bg-white p-4">
    <div class="flex flex-row items-stretch">
      <div class="bg-gray-200 p-4 rounded-md w-3/4"></div>
      <div class="bg-green-200 rounded-2xl ml-2 flex-1"></div>
    </div>
  </div>
</div>

Conclusion

These were actually a lot of fun to make. And I do think they add a nice touch to pages and have more than a few use cases. Tailwind once again made things pretty simple. Am I a Tailwind convert now? I think I’m getting close.