Skip to content

Add loading skeleton for issue cards during HTMX requests #27

Closed

Description

@Ymax27

Context

The Explore page (core/templates/core/explore.html) uses HTMX to load filtered results dynamically. Currently, when filters change, there's only a small spinner (#list-loader at line 74-76) above the results. The issue cards themselves disappear instantly, creating a jarring "flash of empty content" before new results load. Modern UIs use skeleton loaders (placeholder cards) to maintain visual continuity.

What to do

Add CSS-only skeleton loading placeholders that appear during HTMX requests, matching the shape of issue cards.

Files to touch

  • static/css/app.css (add skeleton styles after line 175)
  • core/templates/core/explore.html (add skeleton HTML in a hidden state, shown via HTMX indicator)

Implementation guidance

1. Add skeleton styles to static/css/app.css:

.skeleton {
  background: linear-gradient(90deg, 
    rgb(var(--surface-container)) 25%, 
    rgb(var(--surface-container-low)) 50%, 
    rgb(var(--surface-container)) 75%
  );
  background-size: 200% 100%;
  animation: skeleton-shimmer 1.5s infinite;
  border-radius: 0.5rem;
}
@keyframes skeleton-shimmer {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

2. In core/templates/core/explore.html (after line 79):

<div id="skeleton-loader" class="htmx-indicator grid md:grid-cols-1 gap-4">
  {% for i in "123" %}
  <div class="border border-outline-variant/50 rounded-xl p-5 space-y-3">
    <div class="flex items-center gap-2.5">
      <div class="w-8 h-8 rounded-lg skeleton"></div>
      <div class="flex-1 h-4 skeleton" style="width: 60%;"></div>
    </div>
    <div class="h-5 skeleton" style="width: 80%;"></div>
    <div class="h-4 skeleton" style="width: 90%;"></div>
  </div>
  {% endfor %}
</div>

3. Update form to hide #issue-list during requests:
Add hx-on::before-request="document.getElementById('issue-list').style.opacity='0.3'" to the form tag (line 12), and restore in hx-on::after-swap.

Acceptance criteria

  • When filters change, 3 skeleton cards appear immediately
  • Skeleton animation is smooth (no jank)
  • Real cards replace skeletons when data loads
  • prefers-reduced-motion users see static skeletons (no animation)
  • Works on mobile and desktop viewports

Difficulty: Easy (~1 hour). Great introduction to CSS animations and progressive enhancement.


Questions welcome in the comments, comment here to get assigned. Happy hacking! 🚀

— Max

Activity

  1. sssimransingh26-bit commented on Oct 19, 2026

    @sssimransingh26-bit
    Contributor

    Hi! I'd like to contribute to this issue. My proposed approach is to:

    • Add CSS-only skeleton cards that match the existing issue card layout.
    • Use HTMX loading indicators to show the skeletons while filtered results are loading.
    • Add prefers-reduced-motion support so users who prefer reduced motion see static skeletons.
    • Ensure the real issue cards appear correctly after the request completes, and test the behavior on mobile and desktop.

    I'll first inspect the existing Explore template and HTMX flow to make sure the implementation fits the current structure.

    Would this approach be okay? I'd be happy to work on it if the issue is available.

  2. Ymax27 commented on Oct 19, 2026

    @Ymax27
    OwnerAuthor

    Thanks, that approach sounds great (CSS-only skeletons + HTMX indicator + prefers-reduced-motion is exactly what we want). I've assigned this one to you. 🙌

    Feel free to wrap up #56 first and then open a separate PR for this. Shout here if you have any questions!

    — Max

  3. sssimransingh26-bit commented on Oct 20, 2026

    @sssimransingh26-bit
    Contributor

    Hi Max, I noticed PR #57 was linked to this issue after I was assigned. Should I wait for your decision on that PR, or go ahead with my own implementation? I'm finishing up #56 first, as you suggested.

  4. Ymax27 commented on Oct 20, 2026

    @Ymax27
    OwnerAuthor

    Go ahead with your own implementation. The issue is assigned to you, so #57 doesn't change anything here. Looking forward to your PR once #56 is merged! 🙂

    — Max

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions