Tips & Tricks (अपडेट: 2/6/2026)

Claude Code से Skeleton Loading: React, CLS और Accessibility

Claude Code से skeleton loading लागू करें: React उदाहरण, CLS नियंत्रण, accessibility, pitfalls और checks.

Claude Code से Skeleton Loading: React, CLS और Accessibility

Skeleton loading वह UI pattern है जिसमें data आने से पहले page की लगभग वही बनावट दिखाई जाती है। आसान भाषा में, image, title, summary और action button की जगह पहले से reserved कर दी जाती है, ताकि असली content आते समय layout अजनबी न लगे।

Spinner सिर्फ बताता है कि “कुछ load हो रहा है”। Skeleton यह भी बताता है कि “यहां किस तरह का content आने वाला है”। अगर image, ad slot या API response पहले से तय space में आता है, तो page के अचानक हिलने की संभावना कम होती है। यह stability web.dev के Cumulative Layout Shift और Core Web Vitals guidance से जुड़ी है।

इस guide में हम Claude Code को skeleton loading के लिए कैसे prompt करें, copy-paste चलने वाला React example, CSS motion, accessibility, failure cases और lightweight checks देखेंगे। Related topics के लिए Claude Code performance optimization, image lazy loading और accessibility workflow भी पढ़ें।

पहले काम को हिस्सों में बांटें

Skeleton loading केवल gray rectangle दिखाना नहीं है। Real feature में loading, success, empty और error states चाहिए। इन सभी states में layout जितना संभव हो उतना stable रहना चाहिए। अगर आप Claude Code से सिर्फ “सुंदर skeleton बना दो” कहेंगे, तो वह shimmer effect बना सकता है, लेकिन error UI, reduced motion और screen reader message छूट सकते हैं।

flowchart LR
  P["Claude Code prompt"] --> S["लगभग समान आकार का skeleton"]
  S --> D["loaded data"]
  D --> E["empty state"]
  D --> X["error state"]
  S --> A["aria-busy / status"]
  S --> M["prefers-reduced-motion"]
  S --> C["CLS check"]

शुरू में scope और verification साथ दें:

Read the existing card/list components before editing.
Implement skeleton loading only for the article cards list.
Keep the skeleton dimensions close to the loaded content.
Handle loading, empty, error, and success states.
Respect prefers-reduced-motion and avoid layout shift.
Add a small Playwright check if the project already uses Playwright.
Do not change unrelated styles, routing, or data fetching.

prefers-reduced-motion CSS की condition है जो बताती है कि user ने system या browser में motion कम करने की preference चुनी है या नहीं। तेज shimmer कुछ users के लिए असुविधाजनक हो सकता है, इसलिए MDN का prefers-reduced-motion reference देखें और बिना animation वाला fallback रखें।

Practical use cases

Skeleton loading उन screens में सबसे उपयोगी है जहां user समझ सकता है कि क्या आने वाला है, पर data अभी तैयार नहीं है।

Use caseक्या reserve करेंध्यान देने वाली बात
Article card listThumbnail, दो line title, summary, tagMedia height fixed रखें ताकि card न उछले
DashboardKPI card, chart frame, recent activityअधूरे numbers पहले दिखाकर भ्रम न बनाएं
Ecommerce gridProduct image, name, price, ratingRefresh के समय पुराना price या stock सच जैसा न लगे
Admin tableHeader, rows, action buttonsRows बहुत बदलती हैं तो pagination भी देखें
Consulting या content LPProof cards, CTA, FAQLate CTA conversion path को नीचे धकेल सकता है

ClaudeCodeLab के consulting flow में Masa ने देखा कि article cards और CTA की height पहले reserve करने से सबसे ज्यादा फर्क पड़ा। गलती तब हुई जब skeleton final content से लंबा था। Loading के दौरान page शांत लगा, लेकिन content आते ही ऊपर खिसक गया। Skeleton decoration नहीं है; यह final layout के साथ contract है।

Copy-paste React example

नीचे का example Vite + React + TypeScript project के src/App.tsx में paste करके चला सकते हैं। यह setTimeout से latency simulate करता है और success, empty, error states switch कराता है। Real repository edit कराने से पहले Claude Code को इसी level तक state behavior बताना बेहतर है।

import { useEffect, useState } from "react";
import "./skeleton-demo.css";

type Article = {
  id: number;
  title: string;
  description: string;
  tag: string;
};

type LoadState = "loading" | "success" | "empty" | "error";

const demoArticles: Article[] = [
  {
    id: 1,
    title: "Claude Code से सुरक्षित UI diff बनाना",
    description: "पहले existing components पढ़ें, फिर केवल loading experience सुधारें।",
    tag: "UX",
  },
  {
    id: 2,
    title: "CLS बढ़ाए बिना image space reserve करना",
    description: "Data आने से पहले media, title और summary heights fixed रखें।",
    tag: "Performance",
  },
  {
    id: 3,
    title: "Accessible loading states",
    description: "aria-busy, status message और reduced motion behavior साथ रखें।",
    tag: "A11y",
  },
];

function SkeletonLine({ width = "100%" }: { width?: string }) {
  return <span className="sk-line" style={{ width }} aria-hidden="true" />;
}

function ArticleCardSkeleton() {
  return (
    <article className="article-card is-skeleton" aria-hidden="true">
      <div className="sk-media" />
      <div className="article-card__body">
        <SkeletonLine width="46%" />
        <SkeletonLine />
        <SkeletonLine width="86%" />
        <SkeletonLine width="32%" />
      </div>
    </article>
  );
}

function ArticleCard({ article }: { article: Article }) {
  return (
    <article className="article-card">
      <div className="article-card__media">{article.tag}</div>
      <div className="article-card__body">
        <p className="article-card__tag">{article.tag}</p>
        <h2>{article.title}</h2>
        <p>{article.description}</p>
      </div>
    </article>
  );
}

export default function App() {
  const [state, setState] = useState<LoadState>("loading");
  const [articles, setArticles] = useState<Article[]>([]);

  useEffect(() => {
    const timer = window.setTimeout(() => {
      setArticles(demoArticles);
      setState("success");
    }, 1200);

    return () => window.clearTimeout(timer);
  }, []);

  const reloadAs = (nextState: LoadState) => {
    setState("loading");
    setArticles([]);

    window.setTimeout(() => {
      setArticles(nextState === "success" ? demoArticles : []);
      setState(nextState);
    }, 700);
  };

  return (
    <main className="demo-shell">
      <div className="demo-toolbar" aria-label="दिखाई जाने वाली state बदलें">
        <button onClick={() => reloadAs("success")}>Success</button>
        <button onClick={() => reloadAs("empty")}>Empty</button>
        <button onClick={() => reloadAs("error")}>Error</button>
      </div>

      <section
        aria-busy={state === "loading"}
        aria-describedby="article-list-status"
        className="article-grid"
      >
        <p id="article-list-status" className="sr-only" role="status">
          {state === "loading" ? "Article list load हो रही है" : "Article list loaded है"}
        </p>

        {state === "loading" &&
          Array.from({ length: 3 }).map((_, index) => (
            <ArticleCardSkeleton key={index} />
          ))}

        {state === "success" &&
          articles.map((article) => (
            <ArticleCard key={article.id} article={article} />
          ))}

        {state === "empty" && (
          <div className="state-panel">अभी दिखाने के लिए article नहीं हैं।</div>
        )}

        {state === "error" && (
          <div className="state-panel" role="alert">
            Article list load नहीं हो सकी। कृपया बाद में फिर कोशिश करें।
          </div>
        )}
      </section>
    </main>
  );
}

Accessibility में सबसे जरूरी बात है कि skeleton shapes को जरूरत से ज्यादा announce न कराया जाए। Screen reader को यह सुनना जरूरी नहीं कि तीन gray lines हैं। ऊपर के example में skeleton cardsaria-hidden हैं, जबकि list state एक हीrole="status" message से बताई जाती है। Non-urgent updates के लिए MDN का ARIA status role reference उपयोगी है।

Stable size और motion के लिए CSS

नीचे का CSSsrc/skeleton-demo.css में save करें। मुख्य बात यह है कि loading और loaded state मेंmin-height, media height और spacing बहुत अलग न हों। Shimmer हल्का है और reduced motion preference होने पर बंद हो जाता है।

:root {
  color: #18212f;
  background: #f6f7f9;
  font-family: Inter, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}

button {
  min-height: 40px;
  border: 1px solid #b8c2d6;
  border-radius: 8px;
  background: #ffffff;
  color: #18212f;
  padding: 0 14px;
  font-weight: 700;
}

.demo-shell {
  width: min(1040px, calc(100% - 32px));
  margin: 40px auto;
}

.demo-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 18px;
}

.article-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 16px;
}

.article-card {
  min-height: 316px;
  overflow: hidden;
  border: 1px solid #d7deea;
  border-radius: 8px;
  background: #ffffff;
}

.article-card__media,
.sk-media {
  display: grid;
  min-height: 148px;
  place-items: center;
  background: #dfe7f3;
  color: #39506f;
  font-weight: 800;
}

.article-card__body {
  display: grid;
  gap: 10px;
  padding: 18px;
}

.article-card__tag {
  color: #3b6b4f;
  font-size: 0.875rem;
  font-weight: 800;
}

.article-card h2 {
  min-height: 56px;
  margin: 0;
  font-size: 1.16rem;
  line-height: 1.45;
}

.article-card p {
  margin: 0;
  line-height: 1.7;
}

.sk-line,
.sk-media {
  border-radius: 8px;
  background: linear-gradient(90deg, #d9e0ea 25%, #edf1f7 37%, #d9e0ea 63%);
  background-size: 240% 100%;
  animation: skeleton-shimmer 1.4s ease-in-out infinite;
}

.sk-line {
  display: block;
  height: 16px;
}

.state-panel {
  min-height: 180px;
  display: grid;
  place-items: center;
  border: 1px solid #d7deea;
  border-radius: 8px;
  background: #ffffff;
  padding: 24px;
  text-align: center;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
}

@keyframes skeleton-shimmer {
  from {
    background-position: 120% 0;
  }

  to {
    background-position: -120% 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .sk-line,
  .sk-media {
    animation: none;
    background: #d9e0ea;
  }
}

यह CSS चमकदार effect से ज्यादा layout stability को प्राथमिकता देता है। अगर skeleton lines की width बहुत random होगी, तो final content आते समय design बदलता हुआ लगेगा। बेहतर है कि दो-line title, दो-line summary और fixed media area पहले से तय कर दिए जाएं।

Playwright से छोटी जांच

अगर project पहले से Playwright use करता है, तो एक focused test जोड़ें। यह real-world CLS को पूरी तरह prove नहीं करता, लेकिन review से पहले स्पष्ट regression पकड़ सकता है।

import { expect, test } from "@playwright/test";

test("article skeleton keeps a stable card area", async ({ page }) => {
  await page.goto("/");

  await expect(page.getByText("Article list load हो रही है")).toBeAttached();
  await expect(page.locator(".is-skeleton")).toHaveCount(3);

  const firstBox = await page.locator(".article-card").first().boundingBox();
  expect(firstBox?.height).toBeGreaterThan(280);

  await page.getByRole("button", { name: "Error" }).click();
  await expect(page.getByRole("alert")).toContainText("load नहीं हो सकी");
});

Real CLS images, ads, fonts, third-party scripts, network और device पर भी निर्भर करता है। इस test को early warning की तरह रखें, फिर web.dev guidance और production data से मजबूत निष्कर्ष निकालें।

Common pitfalls

पहला pitfall है skeleton का final content से match न होना। Loading में सब ठीक दिखता है, लेकिन real card आते ही height बदल जाती है। Image के लिएwidth, height याaspect-ratio तय करें, और ads तथा CTA के लिए भी पहले space रखें।

दूसरा pitfall है हर fast request पर skeleton दिखाना। अगर request आम तौर पर 100ms में खत्म होती है, तो skeleton flicker बन सकता है। Production में “300ms के बाद दिखाएं”, “सिर्फ first load पर दिखाएं” या “refresh में पुराना data दिखाते रहें” जैसे rules बेहतर होते हैं।

तीसरा pitfall है accessibility announcements बहुत ज्यादा करना। हर card मेंrole="status" डालने से repeated messages आ सकते हैं। Live message list level पर रखें और purely visual skeleton shapes को hidden रखें।

चौथा pitfall है error state न बनाना। API fail होने पर skeleton हमेशा दिखता रहे तो user समझेगा कि page अभी भी load हो रहा है। Error, empty और retry को अलग states की तरह design करें।

पांचवां pitfall है product priority Claude Code पर छोड़ना। Claude Code files पढ़कर code बना सकता है, लेकिन कौन सा CTA visible रहे, ad space कितना reserve हो और कौन सा content पहले दिखे, यह human decision है।

Claude Code review prompt

Implementation के बाद Claude Code को review mode में चलाएं:

Review only the skeleton loading changes.
Check whether loaded content and skeleton content reserve similar space.
Check loading, success, empty, and error states.
Check reduced-motion behavior and ARIA announcements.
Point out any code that may increase CLS or create repeated screen reader messages.
Return findings with file names and exact lines.

इससे Claude Code implementer से critical reviewer बनता है। Content sites में ads, related posts, CTA और lazy images एक ही visual flow को affect करते हैं। CSS styling guide और testing strategies के साथ visual checks, screen reader checks और regression tests अलग-अलग रखें।

Monetization से संबंध

Skeleton loading revenue paths को भी protect करता है। Consulting CTA, product card, newsletter form या ad slot देर से आकर article को नीचे धकेलते हैं, तो reader अपनी जगह खो सकता है या गलत area पर click कर सकता है। इससे trust और conversion दोनों प्रभावित होते हैं।

Individual builders free Claude Code cheatsheet से review steps standardize कर सकते हैं। Teams अगर skeleton loading, lazy images, Core Web Vitals और accessibility को shared workflow बनाना चाहती हैं, तो Claude Code training और consultation देखें। Masa existing repository देखकर improvement order, prompts, components और checks practical रूप में व्यवस्थित कर सकता है।

Summary

अच्छा skeleton loading wait time छिपाने की trick नहीं है। यह final screen के करीब space reserve करता है, uncertainty कम करता है और visible layout movement घटाता है। Claude Code के साथ target component, states, dimensions, accessibility requirements और verification commands एक साथ दें।

इस workflow को आजमाने पर सबसे उपयोगी बदलाव थे media और title height पहले fix करना, loading status list level पर announce करना और reduced-motion users के लिए animation बंद करना। जब focus केवल shimmer पर था, empty और error states बाद में छूट गए और review लंबा हुआ। Implementation और verification को साथ मांगना ज्यादा व्यावहारिक है।

#Claude Code #skeleton loading #React #UX #accessibility
मुफ़्त

मुफ़्त PDF: Claude Code cheatsheet

Email डालें और commands, review habits तथा safe workflow वाली एक-page PDF पाएँ.

हम आपका data सुरक्षित रखते हैं और spam नहीं भेजते.

Masa

लेखक के बारे में

Masa

Claude Code workflow और team adoption पर काम करने वाला engineer.