PostCSS plugin that transforms CSS :focus-within pseudo-selectors with browser polyfill support
npx @tessl/cli install tessl/npm-postcss-focus-within@9.0.0PostCSS Focus Within enables the use of the :focus-within pseudo-class in CSS by providing both a PostCSS transformation plugin and a browser polyfill. The plugin transforms CSS containing :focus-within selectors into equivalent attribute and class-based fallbacks, while the browser polyfill dynamically applies these fallbacks in browsers that don't support the native selector.
npm install postcss-focus-withinPostCSS Plugin (ESM):
import postcssFocusWithin from "postcss-focus-within";
// Also available as named export:
import postcssFocusWithin, { pluginOptions } from "postcss-focus-within";PostCSS Plugin (CommonJS):
const postcssFocusWithin = require("postcss-focus-within");Browser Polyfill (ESM):
import focusWithin from "postcss-focus-within/browser";Browser Global Polyfill:
<script src="https://unpkg.com/postcss-focus-within@9.0.1/dist/browser-global.js"></script>
<script>focusWithinInit()</script>import postcss from "postcss";
import postcssFocusWithin from "postcss-focus-within";
// PostCSS transformation
const result = await postcss([
postcssFocusWithin({
preserve: true,
replaceWith: "[focus-within]",
disablePolyfillReadyClass: false
})
]).process(css);
// Browser polyfill initialization
import focusWithin from "postcss-focus-within/browser";
focusWithin({ replaceWith: "[focus-within]" });CSS transformation example:
/* Input CSS */
.my-form-field:focus-within label {
background-color: yellow;
}
/* Output CSS */
.my-form-field[focus-within].js-focus-within label,
.js-focus-within .my-form-field[focus-within] label {
background-color: yellow;
}
.my-form-field:focus-within label {
background-color: yellow;
}PostCSS Focus Within is built around two complementary components:
PostCSS transformation plugin that converts :focus-within pseudo-selectors into compatible attribute/class selectors with polyfill-ready class prefixing.
/**
* Creates PostCSS plugin instance for transforming :focus-within selectors
* @param options - Plugin configuration options
* @returns PostCSS plugin object
*/
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;
}Browser polyfill that provides :focus-within behavior by dynamically applying attributes or classes to elements when their descendants receive focus.
/**
* Initialize the focus-within polyfill in the browser
* @param options - Polyfill configuration options
*/
function focusWithin(options?: BrowserOptions): void;
interface BrowserOptions {
/** Force polyfill to run even if browser supports :focus-within. Default: false */
force?: boolean;
/** The replacement selector (class or attribute). Default: "[focus-within]" */
replaceWith?: string;
}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 BrowserOptions {
/** Force polyfill to run even if browser supports :focus-within. Default: false */
force?: boolean;
/** The replacement selector (class or attribute). Default: "[focus-within]" */
replaceWith?: string;
}