askill
pseudo-elements

pseudo-elementsSafety 100Repository

Audit CSS for pseudo-element best practices and View Transitions API usage. Use when reviewing hover effects, decorative layers, or page transitions. Outputs file:line findings.

130 stars
2.6k downloads
Updated 2/7/2026

Package Files

Loading files...
SKILL.md

Pseudo Elements

Review CSS and JavaScript for pseudo-element best practices and View Transitions API usage.

How It Works

  1. Read the specified files (or prompt user for files/pattern)
  2. Check against all rules below
  3. Output findings in file:line format

Rule Categories

PriorityCategoryPrefix
1Before/Afterpseudo-
2View Transitionstransition-
3Native Stylingnative-

Rules

Before/After Rules

pseudo-content-required

::before and ::after require content property to render.

Fail:

.button::before {
  position: absolute;
  background: var(--gray-3);
}

Pass:

.button::before {
  content: "";
  position: absolute;
  background: var(--gray-3);
}

pseudo-over-dom-node

Use pseudo-elements for decorative content instead of extra DOM nodes.

Fail:

<button className={styles.button}>
  <span className={styles.background} /> {/* Unnecessary DOM node */}
  Click me
</button>

Pass:

<button className={styles.button}>
  Click me
</button>
.button::before {
  content: "";
  /* decorative background */
}

pseudo-position-relative-parent

Parent must have position: relative for absolute pseudo-elements.

Fail:

.button::before {
  content: "";
  position: absolute;
  inset: 0;
}
/* .button has no position */

Pass:

.button {
  position: relative;
}

.button::before {
  content: "";
  position: absolute;
  inset: 0;
}

pseudo-z-index-layering

Pseudo-elements need z-index to layer correctly with content.

Fail:

.button::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--gray-3);
}
/* Covers button text */

Pass:

.button {
  position: relative;
  z-index: 1;
}

.button::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--gray-3);
  z-index: -1;
}

pseudo-hit-target-expansion

Use negative inset values to expand hit targets without extra markup.

Fail:

<div className={styles.wrapper}> {/* Extra wrapper for hit target */}
  <a className={styles.link}>Link</a>
</div>

Pass:

.link {
  position: relative;
}

.link::before {
  content: "";
  position: absolute;
  inset: -8px -12px;
}

View Transitions Rules

transition-name-required

Elements participating in view transitions need view-transition-name.

Fail:

document.startViewTransition(() => {
  // No view-transition-name assigned
  targetImg.src = newSrc;
});

Pass:

sourceImg.style.viewTransitionName = "card";
document.startViewTransition(() => {
  sourceImg.style.viewTransitionName = "";
  targetImg.style.viewTransitionName = "card";
});

transition-name-unique

Each view-transition-name must be unique on the page during transition.

Fail:

.card {
  view-transition-name: card;
}
/* Multiple cards with same name */

Pass:

// Assign unique name only to transitioning element
element.style.viewTransitionName = `card-${id}`;

transition-name-cleanup

Remove view-transition-name after transition completes.

Fail:

sourceImg.style.viewTransitionName = "card";
document.startViewTransition(() => {
  targetImg.style.viewTransitionName = "card";
});
// sourceImg still has name, causes conflict on next transition

Pass:

sourceImg.style.viewTransitionName = "card";
document.startViewTransition(() => {
  sourceImg.style.viewTransitionName = "";
  targetImg.style.viewTransitionName = "card";
});

transition-over-js-library

Prefer View Transitions API over JavaScript animation libraries for page transitions.

Fail:

import { motion } from "motion/react";

function ImageLightbox() {
  return (
    <motion.img layoutId="hero" /> // JS-based shared element transition
  );
}

Pass:

function openLightbox(img: HTMLImageElement) {
  img.style.viewTransitionName = "hero";
  document.startViewTransition(() => {
    // Native browser transition
  });
}

transition-style-pseudo-elements

Style view transition pseudo-elements for custom animations.

Fail:

document.startViewTransition(() => { /* ... */ });
// Uses default crossfade

Pass:

::view-transition-group(card) {
  animation-duration: 300ms;
  animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
}

Native Styling Rules

native-backdrop-styling

Use ::backdrop pseudo-element for dialog/popover backgrounds.

Fail:

<>
  <div className={styles.overlay} onClick={close} />
  <dialog className={styles.dialog}>{children}</dialog>
</>

Pass:

dialog::backdrop {
  background: var(--black-a6);
  backdrop-filter: blur(4px);
}

native-placeholder-styling

Use ::placeholder for input placeholder styling, not wrapper elements.

Fail:

<div className={styles.inputWrapper}>
  {!value && <span className={styles.placeholder}>Enter text...</span>}
  <input value={value} />
</div>

Pass:

input::placeholder {
  color: var(--gray-9);
  opacity: 1;
}

native-selection-styling

Use ::selection for text selection styling.

Pass:

::selection {
  background: var(--blue-a5);
  color: var(--gray-12);
}

Output Format

When reviewing files, output findings as:

file:line - [rule-id] description of issue

Example:
components/button/styles.module.css:12 - [pseudo-content-required] ::before missing content property
components/lightbox/index.tsx:45 - [transition-over-js-library] Using motion layoutId instead of View Transitions API

Summary Table

After findings, output a summary:

RuleCountSeverity
pseudo-content-required2HIGH
pseudo-over-dom-node1MEDIUM
transition-name-cleanup1MEDIUM

References

Install

Download ZIP
Requires askill CLI v1.0+

AI Quality Score

89/100Analyzed 3/31/2026

Well-structured technical reference skill for auditing CSS pseudo-elements and View Transitions API. Provides 14 specific rules with clear fail/pass examples, organized into 3 priority categories. Includes actionable output format (file:line), summary table template, and external references. Located in dedicated skills folder with clear usage description. High density of accurate technical content appropriate for reusability across projects.

100
90
80
85
90

Metadata

Licenseunknown
Version-
Updated2/7/2026
Publisherraphaelsalaja

Tags

apiprompting