Sass utility library for feature targeting in Material Design Components Web, enabling conditional CSS styles inclusion/exclusion
npx @tessl/cli install tessl/npm-material--feature-targeting@14.0.0Material Feature Targeting provides infrastructure to allow CSS styles to be included or excluded categorically in Material Design Components Web (MDC Web). It enables developers to conditionally emit styles based on features like structure, animation, color, and typography through a systematic approach using Sass mixins and functions.
npm install @material/feature-targetingModern Sass modules (recommended):
@use "@material/feature-targeting";Legacy import (deprecated):
@import "@material/feature-targeting/functions";
@import "@material/feature-targeting/mixins";
@import "@material/feature-targeting/variables";Prefixed import pattern:
@import "@material/feature-targeting/functions.import";
@import "@material/feature-targeting/mixins.import";
@import "@material/feature-targeting/variables.import";@use "@material/feature-targeting";
@mixin my-component-core-styles($query: feature-targeting.all()) {
$feat-structure: feature-targeting.create-target($query, structure);
$feat-color: feature-targeting.create-target($query, color);
@include feature-targeting.targets($feat-structure) {
display: block;
padding: 16px;
}
@include feature-targeting.targets($feat-color) {
color: blue;
background-color: white;
}
}
// Usage - include all styles (default)
@include my-component-core-styles;
// Usage - include only specific features
@include my-component-core-styles(structure);
@include my-component-core-styles(feature-targeting.any(color, typography));
@include my-component-core-styles(feature-targeting.without(animation));Material Feature Targeting is built around three core concepts:
targets mixinThe system uses a query-based approach where styles are conditionally emitted based on feature matching logic.
Creates feature targets from queries and targeted features for use with the targets mixin.
/**
* Creates a feature target from the given feature query and targeted feature
* @param $feature-query - A feature query (string or map)
* @param $targeted-feature - The feature being targeted (string)
* @returns Feature target map with query and target keys
*/
@function create-target($feature-query, $targeted-feature);Parses feature targets to extract query information and available features.
/**
* Parses a list of feature targets to produce a map containing the feature query and list of available features
* @param $feature-targets - List of feature target maps
* @returns Map with available and query keys
*/
@function parse-targets($feature-targets);Functions for composing complex feature queries using logical operators.
/**
* Creates a feature query that is satisfied iff all of its sub-queries are satisfied
* @param $feature-queries... - Variadic list of feature queries
* @returns Query map with op: all and queries list
*/
@function all($feature-queries...);
/**
* Creates a feature query that is satisfied iff any of its sub-queries are satisfied
* @param $feature-queries... - Variadic list of feature queries
* @returns Query map with op: any and queries list
*/
@function any($feature-queries...);
/**
* Creates a feature query that is satisfied iff its sub-query is not satisfied
* @param $feature-query - A single feature query
* @returns Query map with op: without and queries list
*/
@function without($feature-query);Mixin for conditionally emitting styles based on feature targets.
/**
* Conditionalizes content to only be emitted if the given feature target(s) is/are queried
* @param $feature-targets... - Variadic list of feature target maps
* @content - Sass content block that will be conditionally emitted
* @note Cannot be nested inside another targets mixin call
*/
@mixin targets($feature-targets...);Pre-defined lists of supported features and query operators.
/**
* List of all supported features
* @type List
* @value (structure, color, typography, animation)
*/
$all-features: (structure, color, typography, animation);
/**
* List of all supported query operators
* @type List
* @value (any, all, without)
*/
$all-query-operators: (any, all, without);The library supports four main feature categories:
structure - All baseline styles that don't fit into any other categoryanimation - Styles responsible for causing animations and transitions to occurcolor - Color-specific styles which rely on mdc-theme variablestypography - Typography-specific styles which rely on mdc-typographyBasic Feature Targeting:
@use "@material/feature-targeting";
@mixin button-styles($query: feature-targeting.all()) {
$feat-structure: feature-targeting.create-target($query, structure);
$feat-color: feature-targeting.create-target($query, color);
$feat-animation: feature-targeting.create-target($query, animation);
@include feature-targeting.targets($feat-structure) {
display: inline-block;
padding: 8px 16px;
border: none;
border-radius: 4px;
}
@include feature-targeting.targets($feat-color) {
background-color: #1976d2;
color: white;
}
@include feature-targeting.targets($feat-animation) {
transition: background-color 0.2s ease;
&:hover {
background-color: #1565c0;
}
}
}
// Note: targets mixin cannot be nested
// This will cause an error:
// @include feature-targeting.targets($feat-structure) {
// @include feature-targeting.targets($feat-color) { // ERROR!
// color: red;
// }
// }Query Composition:
// Include multiple features
@include button-styles(feature-targeting.any(structure, color));
// Include all except animations
@include button-styles(feature-targeting.without(animation));
// Include all features (default)
@include button-styles(feature-targeting.all());
// Include only structure
@include button-styles(structure);Complex Queries:
// Multiple exclusions
@include button-styles(
feature-targeting.without(
feature-targeting.any(animation, typography)
)
);
// All features explicitly
@include button-styles(
feature-targeting.all(structure, color, typography, animation)
);For codebases still using @import, the library provides backward compatibility:
Functions only (prefixed):
@import "@material/feature-targeting/functions.import";
$target: mdc-feature-create-target(structure, structure);
$query: mdc-feature-all(structure, color);Mixins only (prefixed):
@import "@material/feature-targeting/mixins.import";
@include mdc-feature-targets($target) {
display: block;
}Variables only (prefixed):
@import "@material/feature-targeting/variables.import";
$features: $mdc-feature-all-features;
$operators: $mdc-feature-all-query-operators;Legacy individual imports (deprecated):
@import "@material/feature-targeting/functions";
@import "@material/feature-targeting/mixins";
@import "@material/feature-targeting/variables";
$target: create-target(structure, structure);
$query: all(structure, color);
@include targets($target) { display: block; }