Shadows and rings add depth and interactivity to your designs. Shadows create visual hierarchy by making elements appear elevated, while rings provide clear focus indicators for accessibility. In this lesson, you'll master box shadows, drop shadows, and ring utilities to create polished, accessible interfaces with proper depth and focus states.
Box Shadows
Box shadows create rectangular shadows around elements, adding depth and elevation:
Shadow Sizes
<!-- No shadow -->
<div class="shadow-none bg-white p-6">
No shadow
</div>
<!-- Small shadow (subtle) -->
<div class="shadow-sm bg-white p-6">
Small shadow - subtle depth
</div>
<!-- Default shadow -->
<div class="shadow bg-white p-6">
Default shadow - moderate depth
</div>
<!-- Medium shadow -->
<div class="shadow-md bg-white p-6">
Medium shadow - noticeable depth
</div>
<!-- Large shadow -->
<div class="shadow-lg bg-white p-6">
Large shadow - strong depth
</div>
<!-- Extra large shadow -->
<div class="shadow-xl bg-white p-6">
Extra large shadow - very elevated
</div>
<!-- 2XL shadow -->
<div class="shadow-2xl bg-white p-6">
2XL shadow - maximum elevation
</div>Shadow Scale
shadow-sm- 0 1px 2px rgba(0,0,0,0.05)shadow- 0 1px 3px rgba(0,0,0,0.1), 0 1px 2px rgba(0,0,0,0.06)shadow-md- 0 4px 6px rgba(0,0,0,0.1)shadow-lg- 0 10px 15px rgba(0,0,0,0.1), 0 4px 6px rgba(0,0,0,0.05)shadow-xl- 0 20px 25px rgba(0,0,0,0.1), 0 10px 10px rgba(0,0,0,0.04)shadow-2xl- 0 25px 50px rgba(0,0,0,0.25)
Inner Shadows
Create inset shadows for pressed or recessed effects:
<!-- Inner shadow (inset) -->
<div class="shadow-inner bg-gray-100 p-6">
Inset shadow - recessed appearance
</div>
<!-- Combine with color for depth -->
<div class="shadow-inner bg-white border border-gray-200 p-6">
Subtle inset effect
</div>
<!-- Button pressed state -->
<button class="bg-blue-500 text-white px-6 py-3 rounded-lg active:shadow-inner">
Click me (press to see inset)
</button>Responsive Shadows
<!-- Increase shadow on larger screens -->
<div class="shadow-sm md:shadow-md lg:shadow-lg bg-white p-6">
Progressive shadow depth
</div>
<!-- Shadow on hover -->
<div class="shadow hover:shadow-lg transition-shadow duration-300 bg-white p-6 rounded-lg cursor-pointer">
Hover for deeper shadow
</div>
<!-- Remove shadow on mobile, add on desktop -->
<div class="shadow-none md:shadow-lg bg-white p-6">
Shadow on desktop only
</div>✨ Shadow Best Practices
- Use
shadow-smfor subtle cards and UI elements - Use
shadow-lgorshadow-xlfor modals and overlays - Increase shadow on hover for interactive elements
- Don't overuse large shadows—they lose impact
- Combine shadows with transitions for smooth effects
Colored Shadows
Add color to shadows for creative effects (great for dark mode or accent colors):
<!-- Blue shadow -->
<div class="shadow-lg shadow-blue-500/50 bg-white p-6 rounded-lg">
Blue-tinted shadow
</div>
<!-- Purple shadow -->
<div class="shadow-xl shadow-purple-500/50 bg-white p-6 rounded-lg">
Purple-tinted shadow
</div>
<!-- Red shadow -->
<div class="shadow-lg shadow-red-500/30 bg-white p-6 rounded-lg">
Red-tinted shadow (30% opacity)
</div>
<!-- Green glow effect -->
<div class="shadow-2xl shadow-green-500/60 bg-white p-6 rounded-lg">
Green glow effect
</div>
<!-- Gradient with colored shadow -->
<div class="bg-gradient-to-r from-blue-500 to-purple-500 shadow-2xl shadow-purple-500/50 text-white p-6 rounded-lg">
Gradient with matching shadow
</div>
<!-- Dark shadow for elevation -->
<div class="shadow-xl shadow-gray-900/30 bg-white p-6 rounded-lg">
Dark shadow for strong contrast
</div>Creative Shadow Effects
<!-- Neon button effect -->
<button class="bg-purple-600 text-white px-8 py-4 rounded-lg shadow-lg shadow-purple-500/50 hover:shadow-xl hover:shadow-purple-500/70 transition-all duration-300">
Neon Button
</button>
<!-- Card with brand shadow -->
<div class="bg-white p-6 rounded-lg shadow-lg shadow-blue-500/20 border border-blue-100">
<h3 class="text-xl font-bold text-blue-900 mb-2">Featured Card</h3>
<p class="text-gray-600">With brand-colored shadow</p>
</div>
<!-- Glowing status indicator -->
<div class="inline-flex items-center gap-2 bg-green-50 text-green-800 px-4 py-2 rounded-full shadow-lg shadow-green-500/40">
<div class="w-2 h-2 bg-green-500 rounded-full"></div>
<span class="text-sm font-semibold">Online</span>
</div>Drop Shadows
Drop shadows follow the actual shape of elements (including transparent areas), perfect for images and SVGs:
<!-- Small drop shadow -->
<img src="logo.png" alt="Logo" class="drop-shadow-sm">
<!-- Default drop shadow -->
<img src="logo.png" alt="Logo" class="drop-shadow">
<!-- Medium drop shadow -->
<img src="logo.png" alt="Logo" class="drop-shadow-md">
<!-- Large drop shadow -->
<img src="logo.png" alt="Logo" class="drop-shadow-lg">
<!-- Extra large drop shadow -->
<img src="logo.png" alt="Logo" class="drop-shadow-xl">
<!-- 2XL drop shadow -->
<img src="logo.png" alt="Logo" class="drop-shadow-2xl">
<!-- No drop shadow -->
<img src="logo.png" alt="Logo" class="drop-shadow-none">Drop Shadow vs Box Shadow
<!-- Box shadow: rectangular shadow around the box -->
<img
src="star.png"
alt="Star"
class="shadow-lg w-24 h-24"
>
<!-- Drop shadow: follows the star's actual shape -->
<img
src="star.png"
alt="Star"
class="drop-shadow-lg w-24 h-24"
>
<!-- Drop shadow on SVG -->
<svg class="w-24 h-24 drop-shadow-lg" viewBox="0 0 24 24">
<path fill="currentColor" d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/>
</svg>
<!-- Text with drop shadow -->
<h1 class="text-6xl font-bold drop-shadow-lg">
Shadowed Text
</h1>Performance Note: Drop shadows can be more resource-intensive than box shadows. Use them when you need the shape-following behavior, but prefer box shadows for better performance when possible.
Ring Utilities
Rings create outline-style borders perfect for focus states. They don't affect layout like regular borders:
Ring Width
<!-- No ring -->
<div class="ring-0 bg-white p-4 rounded-lg">
No ring
</div>
<!-- Default ring (3px) -->
<div class="ring bg-white p-4 rounded-lg">
Default ring (3px)
</div>
<!-- Thin ring (1px) -->
<div class="ring-1 bg-white p-4 rounded-lg">
1px ring
</div>
<!-- 2px ring -->
<div class="ring-2 bg-white p-4 rounded-lg">
2px ring
</div>
<!-- 4px ring -->
<div class="ring-4 bg-white p-4 rounded-lg">
4px ring
</div>
<!-- 8px ring -->
<div class="ring-8 bg-white p-4 rounded-lg">
8px ring
</div>
<!-- Inset ring -->
<div class="ring-4 ring-inset ring-blue-500 bg-blue-50 p-4 rounded-lg">
Inset ring (inside the element)
</div>Ring Colors
<!-- Colored rings -->
<div class="ring-4 ring-blue-500 bg-white p-4 rounded-lg">
Blue ring
</div>
<div class="ring-4 ring-green-500 bg-white p-4 rounded-lg">
Green ring
</div>
<div class="ring-4 ring-purple-500 bg-white p-4 rounded-lg">
Purple ring
</div>
<div class="ring-4 ring-red-500 bg-white p-4 rounded-lg">
Red ring
</div>
<!-- Ring with opacity -->
<div class="ring-4 ring-blue-500/50 bg-white p-4 rounded-lg">
Blue ring with 50% opacity
</div>
<!-- Current color ring -->
<div class="text-purple-600 ring-4 ring-current bg-white p-4 rounded-lg">
Ring matches text color
</div>Focus States with Rings
Rings are perfect for keyboard navigation focus indicators:
<!-- Button with focus ring -->
<button class="bg-blue-500 text-white px-6 py-3 rounded-lg outline-none focus:ring-4 focus:ring-blue-300 transition">
Focus me (use Tab key)
</button>
<!-- Input with focus ring -->
<input
type="text"
class="border border-gray-300 rounded-lg px-4 py-2 outline-none focus:ring-4 focus:ring-blue-200 focus:border-blue-500 transition"
placeholder="Focus for ring"
>
<!-- Card that highlights on focus -->
<div
tabindex="0"
class="bg-white p-6 rounded-lg border border-gray-200 outline-none focus:ring-4 focus:ring-purple-300 focus:border-purple-500 cursor-pointer transition"
>
<h3 class="font-bold mb-2">Focusable Card</h3>
<p class="text-sm text-gray-600">Tab to focus</p>
</div>
<!-- Link with focus ring -->
<a
href="#"
class="inline-block bg-green-500 text-white px-6 py-3 rounded-lg outline-none focus:ring-4 focus:ring-green-300 transition"
>
Focusable Link
</a>♿ Accessibility is Critical
Always provide visible focus states! Users who navigate with keyboards rely on them.
- Never use
outline-nonewithout adding a focus ring - Make focus rings clearly visible (4px+ width)
- Use sufficient color contrast for focus indicators
- Test your UI with keyboard navigation
Ring Offset
Add space between the element and its ring for clearer focus states:
<!-- Ring with 2px offset -->
<button class="bg-blue-500 text-white px-6 py-3 rounded-lg outline-none focus:ring-4 focus:ring-blue-300 focus:ring-offset-2">
Ring with offset
</button>
<!-- Ring with 4px offset -->
<button class="bg-purple-500 text-white px-6 py-3 rounded-lg outline-none focus:ring-4 focus:ring-purple-300 focus:ring-offset-4">
Larger ring offset
</button>
<!-- Ring offset with custom color -->
<button class="bg-green-500 text-white px-6 py-3 rounded-lg outline-none focus:ring-4 focus:ring-green-300 focus:ring-offset-2 focus:ring-offset-gray-100">
Ring offset with background color
</button>
<!-- Dark background example -->
<div class="bg-gray-900 p-8">
<button class="bg-blue-500 text-white px-6 py-3 rounded-lg outline-none focus:ring-4 focus:ring-blue-300 focus:ring-offset-2 focus:ring-offset-gray-900">
Ring offset matches dark background
</button>
</div>Ring Offset Width
<!-- Different ring offset widths -->
<button class="ring-4 ring-blue-500 ring-offset-0 bg-white px-6 py-3 rounded-lg">
No offset
</button>
<button class="ring-4 ring-blue-500 ring-offset-1 bg-white px-6 py-3 rounded-lg">
1px offset
</button>
<button class="ring-4 ring-blue-500 ring-offset-2 bg-white px-6 py-3 rounded-lg">
2px offset
</button>
<button class="ring-4 ring-blue-500 ring-offset-4 bg-white px-6 py-3 rounded-lg">
4px offset
</button>
<button class="ring-4 ring-blue-500 ring-offset-8 bg-white px-6 py-3 rounded-lg">
8px offset
</button>Interactive Shadow Explorer
Experiment with shadow utilities:
Shadow & Ring Explorer
Try different shadow sizes and colors
Utilities
Current Classes:
bg-white rounded-lg p-8 w-64 h-64 flex items-center justify-center text-gray-700 font-semiboldPreview
Practical Shadow & Ring Examples
Example 1: Card Elevation Hierarchy
<!-- Level 1: Flat card (no shadow) -->
<div class="bg-white border border-gray-200 rounded-lg p-6 mb-4">
<h3 class="font-bold mb-2">Flat Card</h3>
<p class="text-sm text-gray-600">No elevation, subtle border</p>
</div>
<!-- Level 2: Slightly raised (subtle shadow) -->
<div class="bg-white shadow-sm rounded-lg p-6 mb-4">
<h3 class="font-bold mb-2">Raised Card</h3>
<p class="text-sm text-gray-600">Subtle shadow for slight elevation</p>
</div>
<!-- Level 3: Elevated (medium shadow) -->
<div class="bg-white shadow-md rounded-lg p-6 mb-4">
<h3 class="font-bold mb-2">Elevated Card</h3>
<p class="text-sm text-gray-600">Medium shadow, more prominent</p>
</div>
<!-- Level 4: Floating (large shadow) -->
<div class="bg-white shadow-lg rounded-lg p-6 mb-4">
<h3 class="font-bold mb-2">Floating Card</h3>
<p class="text-sm text-gray-600">Large shadow, clear separation</p>
</div>
<!-- Level 5: Modal/overlay (extra large shadow) -->
<div class="bg-white shadow-2xl rounded-lg p-6">
<h3 class="font-bold mb-2">Modal Card</h3>
<p class="text-sm text-gray-600">Maximum elevation for overlays</p>
</div>Example 2: Interactive Button States
<!-- Button with hover shadow -->
<button class="bg-blue-500 hover:bg-blue-600 text-white font-semibold px-6 py-3 rounded-lg shadow hover:shadow-lg transition-all duration-200">
Hover Shadow
</button>
<!-- Button with active (pressed) state -->
<button class="bg-purple-500 hover:bg-purple-600 active:bg-purple-700 text-white font-semibold px-6 py-3 rounded-lg shadow-md hover:shadow-lg active:shadow-sm transition-all duration-150">
Click to Press
</button>
<!-- Button with focus ring -->
<button class="bg-green-500 hover:bg-green-600 text-white font-semibold px-6 py-3 rounded-lg shadow outline-none focus:ring-4 focus:ring-green-300 focus:ring-offset-2 transition-all">
Focus Ring
</button>
<!-- Floating action button -->
<button class="bg-red-500 hover:bg-red-600 text-white w-14 h-14 rounded-full shadow-lg hover:shadow-xl hover:-translate-y-1 transition-all duration-200 flex items-center justify-center">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"/>
</svg>
</button>
<!-- Glass morphism button -->
<button class="bg-white/20 backdrop-blur-md border border-white/30 text-white font-semibold px-6 py-3 rounded-lg shadow-lg hover:shadow-xl hover:bg-white/30 transition-all">
Glass Button
</button>Example 3: Form Elements with Focus States
<!-- Text input with focus ring -->
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 mb-2">
Email Address
</label>
<input
type="email"
class="w-full border border-gray-300 rounded-lg px-4 py-2 outline-none focus:ring-4 focus:ring-blue-200 focus:border-blue-500 transition"
placeholder="you@example.com"
>
</div>
<!-- Textarea with focus -->
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 mb-2">
Message
</label>
<textarea
class="w-full border border-gray-300 rounded-lg px-4 py-2 outline-none focus:ring-4 focus:ring-purple-200 focus:border-purple-500 transition resize-none"
rows="4"
placeholder="Your message..."
></textarea>
</div>
<!-- Select with focus -->
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 mb-2">
Country
</label>
<select class="w-full border border-gray-300 rounded-lg px-4 py-2 outline-none focus:ring-4 focus:ring-green-200 focus:border-green-500 transition">
<option>United States</option>
<option>Canada</option>
<option>United Kingdom</option>
</select>
</div>
<!-- Checkbox with focus ring -->
<label class="flex items-center gap-3 cursor-pointer">
<input
type="checkbox"
class="w-5 h-5 text-blue-600 border-gray-300 rounded outline-none focus:ring-4 focus:ring-blue-200 transition"
>
<span class="text-sm text-gray-700">I agree to the terms and conditions</span>
</label>Example 4: Modal Dialog
<!-- Modal overlay -->
<div class="fixed inset-0 bg-black/50 flex items-center justify-center p-4">
<!-- Modal content with large shadow -->
<div class="bg-white rounded-lg shadow-2xl max-w-md w-full p-6">
<!-- Header -->
<div class="flex items-center justify-between mb-4">
<h2 class="text-2xl font-bold text-gray-900">Confirm Action</h2>
<button class="text-gray-400 hover:text-gray-600 outline-none focus:ring-4 focus:ring-gray-200 rounded-lg p-1 transition">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
</svg>
</button>
</div>
<!-- Body -->
<p class="text-gray-600 mb-6">
Are you sure you want to proceed with this action? This cannot be undone.
</p>
<!-- Actions -->
<div class="flex gap-3 justify-end">
<button class="px-6 py-2 bg-gray-200 hover:bg-gray-300 text-gray-800 font-semibold rounded-lg outline-none focus:ring-4 focus:ring-gray-300 transition">
Cancel
</button>
<button class="px-6 py-2 bg-red-600 hover:bg-red-700 text-white font-semibold rounded-lg shadow-md hover:shadow-lg outline-none focus:ring-4 focus:ring-red-300 transition">
Confirm
</button>
</div>
</div>
</div>Example 5: Product Card with Effects
<div class="group bg-white rounded-lg shadow-md hover:shadow-xl transition-all duration-300 overflow-hidden cursor-pointer">
<!-- Image -->
<div class="relative overflow-hidden">
<img
src="product.jpg"
alt="Product"
class="w-full h-64 object-cover group-hover:scale-110 transition-transform duration-300"
>
<!-- Badge with colored shadow -->
<div class="absolute top-4 right-4">
<span class="inline-block bg-red-500 text-white px-3 py-1 rounded-full text-xs font-bold shadow-lg shadow-red-500/50">
20% OFF
</span>
</div>
</div>
<!-- Content -->
<div class="p-6">
<h3 class="text-xl font-bold text-gray-900 mb-2 group-hover:text-blue-600 transition-colors">
Product Name
</h3>
<p class="text-gray-600 mb-4">
High-quality product with amazing features and benefits.
</p>
<!-- Price -->
<div class="flex items-center justify-between mb-4">
<div>
<span class="text-2xl font-bold text-gray-900">$99.99</span>
<span class="text-sm text-gray-500 line-through ml-2">$124.99</span>
</div>
<div class="flex items-center gap-1 text-yellow-500">
<svg class="w-5 h-5 fill-current" viewBox="0 0 20 20">
<path d="M10 15l-5.878 3.09 1.123-6.545L.489 6.91l6.572-.955L10 0l2.939 5.955 6.572.955-4.756 4.635 1.123 6.545z"/>
</svg>
<span class="text-sm text-gray-600 font-semibold">4.8</span>
</div>
</div>
<!-- Button -->
<button class="w-full bg-blue-600 hover:bg-blue-700 text-white font-semibold py-3 rounded-lg shadow hover:shadow-lg outline-none focus:ring-4 focus:ring-blue-300 transition-all">
Add to Cart
</button>
</div>
</div>Example 6: Toast Notifications
<!-- Success toast -->
<div class="bg-green-50 border-l-4 border-green-500 rounded-r-lg shadow-lg shadow-green-500/20 p-4 mb-4">
<div class="flex items-start gap-3">
<svg class="w-6 h-6 text-green-500 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/>
</svg>
<div>
<p class="font-semibold text-green-800">Success!</p>
<p class="text-sm text-green-700">Your changes have been saved.</p>
</div>
</div>
</div>
<!-- Error toast -->
<div class="bg-red-50 border-l-4 border-red-500 rounded-r-lg shadow-lg shadow-red-500/20 p-4 mb-4">
<div class="flex items-start gap-3">
<svg class="w-6 h-6 text-red-500 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd"/>
</svg>
<div>
<p class="font-semibold text-red-800">Error!</p>
<p class="text-sm text-red-700">Something went wrong. Please try again.</p>
</div>
</div>
</div>
<!-- Info toast -->
<div class="bg-blue-50 border-l-4 border-blue-500 rounded-r-lg shadow-lg shadow-blue-500/20 p-4">
<div class="flex items-start gap-3">
<svg class="w-6 h-6 text-blue-500 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" clip-rule="evenodd"/>
</svg>
<div>
<p class="font-semibold text-blue-800">Information</p>
<p class="text-sm text-blue-700">New updates are available.</p>
</div>
</div>
</div>Shadow & Ring Playground
Experiment with shadows and rings:
Shadows & Rings Practice
Try different shadow depths and focus states
Interactive Card
This card has shadows that change on hover and buttons with focus rings.
Shadow & Ring Best Practices
Follow These Guidelines:
- Establish hierarchy: Use different shadow sizes for different elevation levels
- Be consistent: Use the same shadow for similar elements
- Animate shadows: Add transitions for smooth hover/focus effects
- Don't overdo it: Too many large shadows create visual chaos
- Always provide focus states: Use rings for keyboard navigation
- Ring offset for clarity: 2-4px offset makes focus states clearer
- Match ring to brand: Use brand colors for focus rings
- Test accessibility: Ensure focus states are clearly visible
- Consider performance: Use box shadows over drop shadows when possible
Key Takeaways
- Box shadows:
shadow-smthroughshadow-2xl - Inner shadows:
shadow-innerfor recessed effects - Colored shadows: Add
/opacityto shadow colors - Drop shadows: Follow element shape, great for images/SVGs
- Rings: Perfect for focus states, don't affect layout
- Ring width:
ring-1throughring-8 - Ring offset: Add space between element and ring
- Always combine
outline-nonewith focus rings - Use transitions for smooth shadow/ring animations
- Shadows create visual hierarchy and depth
What's Next?
Congratulations! You've completed the Borders & Effects category. You now know how to add depth, focus states, and polish to your interfaces with shadows and rings.
You've built a strong foundation in Tailwind CSS fundamentals! In the upcoming lessons, you'll learn about responsive design, transforms, transitions, animations, and advanced techniques to create truly dynamic, interactive interfaces.
🎯 Practice Challenge!
Create a set of interactive cards that demonstrate different elevation levels. Add hover effects that increase shadow depth, include buttons with proper focus rings, and use colored shadows for creative accents. Make sure all interactive elements have clear, accessible focus states!