Lil tips

Uncommon Tailwind css classes

Peer Selectors

// Style based on descendants of a peer
<div>
  <span className="peer">Hover,click me</span>
  <span className="peer-hover:text-foreground/10">hidden on hover</span>
  <span className="peer-active:text-blue">hidden on active</span>
</div>
Hove here Click hereexplore hover effectexplore active effect

has hover Selectors

<div className="has-[span:hover]:text-foreground/10">
  try hovering the hover me →{" "}
  <span className="hover:text-foreground"> hover me only </span>← and observe
</div>
try hovering the hover me → hover me ← and observe

Custom Breakpoints

// Apply styles when viewport is at most 1000px wide
<div className="max-[1000px]:text-red-500 max-[1400px]:text-green-500 text-sky-500  ">
  Observer the color of this text
</div>
Now try resizing the window and observe below
Observer the color of this text

Text clamp

<div className="text-[clamp(40px,8vw,180px)]">Type Shit</div>
Now try resizing the window and see the max size of font is 180px the min is 45px and else is relative to screen size cool right ?
Type Shit

group selector

// Scale down when clicked/active
<div className="group/link">
  try hovering the whole group
  <span className="group-hover/link:text-foreground/10"> the link </span> and
  observe
</div>

Child Data Selectors

// Select any element with data-slot=' a' (note the space)
<div className="*:data-[slot='text']:text-red-500">
  <div data-slot="text">This will have red background</div>
</div>
This will have red background

Descendant Data Selectors

<div className="**:data-[slot='text']:text-red-500 my-2 ">
  <div>
    <div data-slot="text">This will have red background too</div>
  </div>
</div>
This will have red background too

Descendant Selectors

// Typical approach
<ul>
  <li className="px-3 py-2">
    CSS <span className="border">Great</span>
  </li>
  <li className="px-3 py-2">
    Tailwind <span className="border">Fine</span>
  </li>
</ul>

// with child selector approach

<ul className="[&_li]:px-3 [&_li]:py-2 [&_span]:border">
  <li>
    CSS <span>Great</span>
  </li>
  <li>
    Tailwind <span>Fine</span>
  </li>
</ul>

// Select direct child with attribute selector
<div className="[&>[data-slot='bg']]:bg-green-500/10">
  <div data-slot="bg">Direct child with green background</div>
</div>

Direct Descendant Selectors [&> ]:

// Target Direct Decendent only elements
<div className="[&>article>h2]:text-2xl [&>article>p]:text-gray-600">
  <article>
    <h2>Title (2xl)</h2>
    <p>Content (gray)</p>
  </article>
</div>

Title (2xl)

Content (gray)

Nth Child Selectors

<ul>
  {["Item 1", "Item 2", "Item 3", "Item 4","Item 5"].map((item, index) => (
    <li
      key={index}
      className="border-foreground/40 odd:bg-foreground/5  even:bg-foreground/12 first:border-t  p-3  last:border-b"
    >
      {item}
    </li>
  ))}
</ul>

    Sibling Selectors

    // Target all following siblings
    <div>
      <div className="[&~div]:text-gray-500 mt-4 ">First</div>
      <div>Second (gray text)</div>
      <div>Third (gray text)</div>
    </div>
    
    First
    Second (gray text)
    Third (gray text)

    Text Truncation with Line Clamp

    // Show only 2 lines of text with ellipsis
    <div className="line-clamp-2">
      This is a long text that will be truncated after 2 lines...
    </div>
    

    Active State Scaling

    // Scale down when clicked/active
    <button className="transition-transform ease-in-out active:scale-95">
      Click me!
    </button>
    

    Placeholder Styling

    // Style input placeholders
    <input
      className="placeholder:italic placeholder:text-gray-400"
      placeholder="Enter your text..."
    />
    

    Caret Color

    // Customize text cursor color
    <input className="caret-blue-500" />
    

    After Pseudo-element with Inset to increase hit area

    // After with inset positioning
    <div className="relative p-4 bg-muted after:content-[''] after:absolute after:inset-2 after:bg-blue-500 after:opacity-20">
      After with inset-2 (8px from all sides)
    </div>
    
    <div className="relative p-4 bg-muted after:content-[''] after:absolute after:inset-3 after:bg-green-500 after:opacity-20">
      After with inset-3 (12px from all sides)
    </div>
    
    After with inset-2 (8px from all sides)
    After with -inset-3 (-12px from all sides)

    After Bottom Line with Animation

    // Animated bottom line using before pseudo-element
    <button className="relative before:pointer-events-none before:absolute before:bottom-0 before:left-0 before:h-[0.05em] before:w-full before:origin-right before:scale-x-0 before:bg-current before:transition-transform before:duration-300 before:ease-[cubic-bezier(0.4,0,0.2,1)] before:content-[''] hover:before:origin-left hover:before:scale-x-100">
      hover me
    </button>
    

    Outline and Outline Offset

    // Outline with offset
    <div className="bg-muted p-4 outline outline-2 outline-offset-2 outline-blue-500">
      Outline with 2px offset
    </div>
    

    Breakpoint Indicator

    The first thing i do before starting a new project is to add this component to the layout.tsx so i can see the current breakpoint and adjust the design accordingly. and the best part if i forget to remove it in production with vercel automaticaly removes it as its in the production build.
    export function BreakpointIndicator() {
      if (process.env.NODE_ENV === "production") return null;
    
      return (
        <div className="fixed bottom-1 left-1 z-50 flex size-6 items-center justify-center rounded-full bg-gray-800 p-3 font-mono text-xs text-white">
          <div className="block sm:hidden">xs</div>
          <div className="hidden sm:block md:hidden">sm</div>
          <div className="hidden md:block lg:hidden">md</div>
          <div className="hidden lg:block xl:hidden">lg</div>
          <div className="hidden xl:block 2xl:hidden">xl</div>
          <div className="hidden 2xl:block">2xl</div>
        </div>
      );
    }
    
    npx shadcn add @skiper-ui/skiper65
    
    Go Back