컴포넌트
건너뛰기 링크
키보드 포커스를 받을 때만 떠서 본문으로 바로 건너뛰게 해 주는 칩이에요.
- #arc
- #component
- #accessibility
- #keyboard
- #focus
- #navigation
1280px
설치
이 명령 한 줄이면 필요한 파일과 패키지가 함께 설치돼요.
터미널터미널터미널bash
npx shadcn@latest add https://dsui.vercel.app/r/skip-link.json파일
components/arc/skip-link/skip-link.module.csscomponents/arc/skip-link/skip-link.tsx
함께 오는 항목
skip-link.module.cssskip-link.module.cssskip-link.module.csscss
/* Out of sight but still in the tab order: it is moved off the top edge rather than display: none, which would drop it from the order entirely. */
.link { position: fixed; z-index: 100; inset-block-start: var(--space-3); inset-inline-start: var(--space-3); display: inline-flex; min-height: var(--control-height-md); align-items: center; border: 1px solid var(--float-edge, var(--surface-raised)); border-radius: var(--radius-control); padding: 0 var(--space-4); background: var(--surface-raised); color: var(--foreground); box-shadow: var(--shadow-floating); font-size: var(--label-md); font-weight: var(--label-weight); line-height: var(--leading-body); text-decoration: none; opacity: 0; transform: translateY(calc(-100% - var(--space-6))); transition: transform var(--duration-fast) var(--ease-standard), opacity var(--duration-fast) var(--ease-standard); }
.link:focus-visible { opacity: 1; transform: translateY(0); }
/* The global outline would double the chip's own edge, so the chip draws its focus with the accent border instead. */
.link:focus-visible { outline: 2px solid var(--accent-strong); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) { .link { transition: none; } }
skip-link.tsxskip-link.tsxskip-link.tsxtsx
import type { AnchorHTMLAttributes } from "react";
import styles from "./skip-link.module.css";
export interface SkipLinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
/** The id of the landmark to jump to, with the hash: "#main". */
href: string;
}
/**
* The first thing in the tab order: a chip that stays out of sight until keyboard focus reaches it, then floats over
* the page so the reader can jump straight past the header. It is a floating layer, so its border matches its fill
* and the shadow draws the edge.
*/
export function SkipLink({ className, href, children, ...props }: SkipLinkProps) {
return (
<a {...props} href={href} className={[styles.link, className].filter(Boolean).join(" ")}>
{children}
</a>
);
}
SkipLink.displayName = "SkipLink";
export default SkipLink;