CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-postcss-focus-within

PostCSS plugin that transforms CSS :focus-within pseudo-selectors with browser polyfill support

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

postcss-plugin.mddocs/

PostCSS Plugin

The PostCSS Focus Within plugin transforms CSS containing :focus-within pseudo-selectors into compatible attribute/class selectors with optional polyfill-ready class prefixing for browsers that don't support the native selector.

Capabilities

Plugin Factory Function

Creates a PostCSS plugin instance that transforms :focus-within selectors in CSS rules.

/**
 * Creates PostCSS plugin instance for transforming :focus-within selectors
 * @param options - Plugin configuration options
 * @returns PostCSS plugin object with postcssPlugin property
 */
function postcssFocusWithin(options?: pluginOptions): Plugin;

interface pluginOptions {
  /** Preserve the original notation. Default: true */
  preserve?: boolean;
  /** The replacement class/attribute to be used in the polyfill. Default: "[focus-within]" */
  replaceWith?: string;
  /** Disable the selector prefix that prevents flash of incorrectly styled content. Default: false */
  disablePolyfillReadyClass?: boolean;
}

interface Plugin {
  /** PostCSS plugin identifier */
  postcssPlugin: string;
  /** Plugin preparation function */
  prepare(): PluginProcessor;
}

interface PluginProcessor {
  /** PostCSS plugin identifier */
  postcssPlugin: string;
  /** Rule processing function */
  Rule(rule: Rule, helpers: { result: Result }): void;
}

Usage Examples:

import postcss from "postcss";
import postcssFocusWithin from "postcss-focus-within";

// Basic usage with default options
const result = await postcss([
  postcssFocusWithin()
]).process(css);

// With custom options
const result = await postcss([
  postcssFocusWithin({
    preserve: false,
    replaceWith: ".focus-within",
    disablePolyfillReadyClass: true
  })
]).process(css);

Plugin Options

preserve

Controls whether the original :focus-within rules are preserved in the output CSS.

preserve?: boolean; // Default: true

Usage:

// Keep original rules (default)
postcssFocusWithin({ preserve: true });

// Remove original rules
postcssFocusWithin({ preserve: false });

Example transformation with preserve: false:

/* Input */
.form:focus-within { border: blue; }

/* Output */
.form[focus-within].js-focus-within, .js-focus-within .form[focus-within] { 
  border: blue; 
}

replaceWith

Defines the selector used to replace :focus-within in the generated fallback rules.

replaceWith?: string; // Default: "[focus-within]"

Usage:

// Use attribute selector (default)
postcssFocusWithin({ replaceWith: "[focus-within]" });

// Use class selector
postcssFocusWithin({ replaceWith: ".focus-within" });

// Use custom attribute
postcssFocusWithin({ replaceWith: "[data-focus-within]" });

Example transformation with replaceWith: ".focus-within":

/* Input */
.form:focus-within { border: blue; }

/* Output */
.form.focus-within.js-focus-within, .js-focus-within .form.focus-within { 
  border: blue; 
}
.form:focus-within { border: blue; }

disablePolyfillReadyClass

Controls whether selectors are prefixed with the .js-focus-within class that indicates the polyfill is loaded and active.

disablePolyfillReadyClass?: boolean; // Default: false

Usage:

// Include polyfill-ready class (default)
postcssFocusWithin({ disablePolyfillReadyClass: false });

// Disable polyfill-ready class
postcssFocusWithin({ disablePolyfillReadyClass: true });

Example transformation with disablePolyfillReadyClass: true:

/* Input */
.form:focus-within { border: blue; }

/* Output */
.form[focus-within] { border: blue; }
.form:focus-within { border: blue; }

Plugin Static Properties

The plugin function includes a static property to identify it as a PostCSS plugin.

postcssFocusWithin.postcss: true;

Error Handling

The plugin validates the replaceWith option and provides warnings for invalid selectors:

// Invalid selector examples that will trigger warnings:
postcssFocusWithin({ replaceWith: ".class > .child" }); // Contains >
postcssFocusWithin({ replaceWith: "[attr]:hover" });    // Contains :
postcssFocusWithin({ replaceWith: "#id" });             // Contains #

Invalid replaceWith values cause the plugin to warn and skip transformation, as such selectors cannot be applied to single elements.

Install with Tessl CLI

npx tessl i tessl/npm-postcss-focus-within

docs

browser-polyfill.md

index.md

postcss-plugin.md

tile.json