0Pricing
Tailwind CSS Academy · 강의

Focus 및 Focus-Visible 변형

키보드 탐색에는 focus:* 스타일을 적용하고, focus-visible:*로 마우스 클릭이 아닌 키보드 사용자에게만 포커스 링을 표시합니다.

Focus 및 Focus-Visible 변형은(는) CoddyKit의 무료 Tailwind CSS Academy 강의입니다. 이것은 4개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Tailwind CSS Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Tailwind CSS Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

이 강의의 일부는 아직 번역되지 않았으며 영어로 표시됩니다.

The Importance of Focus Styles

Keyboard navigation is used by people with motor disabilities, power users, and anyone filling out a long form. When an element is focused via keyboard, the browser highlights it with a focus indicator. CSS's :focus pseudo-class triggers on any focus event, while :focus-visible triggers only when the browser determines a visible focus indicator is helpful — typically keyboard navigation. Tailwind provides both as focus: and focus-visible: variant prefixes.

<!-- focus-visible is the accessible modern choice -->
<div class="flex gap-4">
  <button class="bg-blue-500 text-white px-4 py-2 rounded focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2">
    Tab to me
  </button>
</div>

focus: Variant Basics

The focus: variant applies a style whenever the element receives focus, regardless of how — mouse click, touch, or keyboard. The most common use is removing the browser's default focus outline and replacing it with a custom ring: focus:outline-none focus:ring-2 focus:ring-blue-500. While convenient, this pattern has a downside: mouse users see the ring on click too, which some designers consider visually intrusive.

<!-- focus: fires on both mouse click and keyboard tab -->
<div class="space-y-3 max-w-sm">
  <input
    type="text"
    placeholder="Click or tab to focus"
    class="w-full border border-gray-300 rounded-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
  />
  <button class="w-full bg-gray-200 py-2 rounded-lg focus:outline-none focus:ring-2 focus:ring-gray-500">
    Focus-on-click-too button
  </button>
</div>

focus-visible: The Modern Approach

focus-visible: maps to the CSS :focus-visible pseudo-class. Browsers apply this only when they determine that showing a focus indicator is appropriate — which means keyboard navigation but typically not mouse clicks on buttons. This gives you the best of both worlds: mouse users do not see the ring, but keyboard users always get clear feedback. This is the recommended approach in all modern Tailwind projects.

<!-- focus-visible: only shows ring for keyboard, not mouse -->
<div class="space-y-3 max-w-sm">
  <!-- Try: click with mouse (no ring) vs Tab key (ring appears) -->
  <button class="w-full bg-blue-500 text-white py-2 rounded-lg focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2">
    Smart focus (use Tab key)
  </button>

  <input
    type="text"
    placeholder="Input: ring on keyboard focus"
    class="w-full border border-gray-300 rounded-lg px-4 py-2 focus:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500"
  />
</div>

Custom Focus Color Conventions

Choose focus ring colors that contrast with both the element and the page background. Brand color rings work well: focus-visible:ring-indigo-500 for an indigo-branded product. Error state focus can use focus:ring-red-500 on invalid inputs. Dark mode requires considering whether your ring color has enough contrast against dark backgrounds — light rings (ring-white or ring-blue-300) work better on dark surfaces.

<!-- Focus colors for different contexts -->
<div class="space-y-4 max-w-sm">
  <!-- Normal: brand color ring -->
  <input class="w-full border rounded px-3 py-2 focus:outline-none focus:ring-2 focus:ring-indigo-500" placeholder="Brand focus" />

  <!-- Success: green ring -->
  <input class="w-full border border-green-300 rounded px-3 py-2 focus:outline-none focus:ring-2 focus:ring-green-500 bg-green-50" placeholder="Valid input" />

  <!-- Error: red ring -->
  <input class="w-full border border-red-300 rounded px-3 py-2 focus:outline-none focus:ring-2 focus:ring-red-500 bg-red-50" placeholder="Invalid input" />
</div>

Focus Styles for Links

Links are among the most important keyboard-navigable elements. By default, browsers apply a focus outline to links, but you may want to customize it to match your design. The pattern focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:rounded creates a clean ring that fits snugly around inline text links, making them clearly identifiable during keyboard navigation.

<!-- Accessible link focus styles -->
<p class="text-gray-700 leading-relaxed max-w-prose">
  Visit our
  <a href="#" class="text-blue-600 underline focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:rounded">
    documentation
  </a>
  to learn more about
  <a href="#" class="text-blue-600 underline focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:rounded">
    getting started
  </a>
  with our product.
</p>

Focus Within — Parent Reacting to Child Focus

focus-within: applies to a parent when any of its descendants are focused. This is useful for highlighting an entire form field container (label + input + helper text) when the input inside receives focus, not just the input itself. The visual group expands to indicate which form field group is active, making complex forms easier to navigate.

<!-- Entire form group highlights when input is focused -->
<div class="space-y-3 max-w-sm">
  <!-- Container gets ring when child input is focused -->
  <div class="border border-gray-200 rounded-xl p-3 focus-within:border-blue-500 focus-within:ring-2 focus-within:ring-blue-500/20 transition-all">
    <label class="block text-xs font-medium text-gray-500 mb-1">Email Address</label>
    <input
      type="email"
      class="w-full focus:outline-none text-gray-800"
      placeholder="you@example.com"
    />
  </div>

  <div class="border border-gray-200 rounded-xl p-3 focus-within:border-blue-500 focus-within:ring-2 focus-within:ring-blue-500/20 transition-all">
    <label class="block text-xs font-medium text-gray-500 mb-1">Password</label>
    <input
      type="password"
      class="w-full focus:outline-none text-gray-800"
      placeholder="••••••••"
    />
  </div>
</div>

Focus and Transition for Smooth Rings

Ring and border changes on focus can be animated with Tailwind's transition utilities. transition-shadow animates shadow (which rings use internally), and transition-colors animates border color changes. Setting duration-150 for a quick 150ms transition gives focus styles that feel instant and responsive without being jarring — the right balance for interactive form elements.

<!-- Smoothly animated focus rings -->
<div class="space-y-4 max-w-sm p-4">
  <input
    type="text"
    placeholder="Focus with smooth transition"
    class="w-full border border-gray-300 rounded-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-all duration-150"
  />

  <textarea
    placeholder="Textarea with focus transition"
    rows="3"
    class="w-full border border-gray-300 rounded-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-purple-500 transition-all duration-150 resize-none"
  ></textarea>
</div>

Disabling Focus Styles Responsibly

You may encounter design requests to remove focus outlines entirely — resist this unless you provide an alternative. focus:outline-none alone violates WCAG 2.1 Success Criterion 2.4.7 (Focus Visible). Always pair it with a custom ring, border change, background change, or some other visible indicator. The pattern focus:outline-none focus-visible:ring-2 is the responsible way to remove the default outline while maintaining accessibility.

<!-- ❌ Bad: removes focus with no replacement -->
<button class="bg-blue-500 text-white px-4 py-2 rounded focus:outline-none">
  Inaccessible (no focus indicator)
</button>

<!-- ✅ Good: replaces with custom ring -->
<button class="bg-blue-500 text-white px-4 py-2 rounded focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2">
  Accessible (custom ring)
</button>

Focus in Select and Checkbox Elements

Native form controls like select, checkbox, and radio also respond to focus variants. For selects, the pattern is the same as inputs: focus:outline-none focus:ring-2 focus:ring-blue-500. For checkboxes, the ring wraps the checkbox square, and for radios it wraps the circle. The @tailwindcss/forms plugin provides better defaults for these elements across browsers.

<!-- Focus styles on different form controls -->
<div class="space-y-4 max-w-sm">
  <!-- Select -->
  <select class="w-full border border-gray-300 rounded-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500">
    <option>Option 1</option>
    <option>Option 2</option>
    <option>Option 3</option>
  </select>

  <!-- Checkboxes -->
  <label class="flex items-center gap-3 cursor-pointer">
    <input type="checkbox" class="w-4 h-4 rounded border-gray-300 text-blue-600 focus:ring-2 focus:ring-blue-500" />
    <span>Agree to terms</span>
  </label>

  <!-- Radio -->
  <label class="flex items-center gap-3 cursor-pointer">
    <input type="radio" name="plan" class="w-4 h-4 border-gray-300 text-blue-600 focus:ring-2 focus:ring-blue-500" />
    <span>Monthly plan</span>
  </label>
</div>

Skip Navigation Links

Skip navigation links are the first focusable element on a page, allowing keyboard users to jump directly to the main content and bypass the navigation. They are visually hidden by default but become visible on focus. The pattern uses sr-only combined with focus:not-sr-only focus:absolute to bring the link into view only when a keyboard user tabs to it. This is a WCAG 2.4.1 compliance requirement.

<!-- Skip navigation link: visible only on keyboard focus -->
<a
  href="#main-content"
  class="sr-only focus:not-sr-only focus:absolute focus:top-2 focus:left-2 bg-blue-500 text-white px-4 py-2 rounded font-medium z-50"
>
  Skip to main content
</a>

<nav class="bg-gray-800 text-white px-6 py-4">
  <!-- Navigation items -->
</nav>

<main id="main-content" class="p-6">
  Main content here
</main>

Focus Styles in Dark Mode

Focus rings designed for light mode may disappear or lose contrast in dark mode. Use Tailwind's dark: variant to switch ring colors: focus-visible:ring-blue-500 dark:focus-visible:ring-blue-400 uses a slightly lighter blue in dark mode for better contrast against dark backgrounds. Alternatively, use white rings on dark surfaces: dark:focus-visible:ring-white.

<!-- Focus rings for both light and dark mode -->
<div class="p-6 bg-white dark:bg-gray-900 space-y-3">
  <input
    type="text"
    placeholder="Adaptive focus ring"
    class="w-full bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 text-gray-900 dark:text-white rounded-lg px-4 py-2 focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 dark:focus-visible:ring-blue-400 focus-visible:border-blue-500 max-w-sm"
  />
</div>

Quick Check

Test your understanding of Tailwind CSS Mastery concepts from this lesson.

Lesson Recap

In this lesson you learned: focus: fires on any focus event while focus-visible: fires only for keyboard navigation, focus-within: highlights a parent when any child is focused — great for form field groups, and always pair focus:outline-none with a custom ring to maintain WCAG accessibility. Next up we explore disabled and placeholder variants for form element styling.

자주 묻는 질문

“Focus 및 Focus-Visible 변형” 강의는 무료인가요?

네 — “Focus 및 Focus-Visible 변형” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Tailwind CSS Academy 강의 전체를 잠금 해제할 수 있습니다. Tailwind CSS Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“Focus 및 Focus-Visible 변형”에서 뭘 배우나요?

키보드 탐색에는 focus:* 스타일을 적용하고, focus-visible:*로 마우스 클릭이 아닌 키보드 사용자에게만 포커스 링을 표시합니다. 브라우저에서 직접 실행하는 실습 코드로 Tailwind CSS Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

Tailwind CSS Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 Tailwind CSS Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 2번째 강의입니다.

“Focus 및 Focus-Visible 변형” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 Tailwind CSS Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 Tailwind CSS Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. Hover 및 활성 상태 변형
  2. Focus 및 Focus-Visible 변형
  3. 비활성화 및 자리 표시자 변형
  4. 그룹 및 피어 변형
← Tailwind CSS Academy(으)로 돌아가기