mirror of
https://github.com/tailwindlabs/tailwindcss.git
synced 2025-12-08 21:36:08 +00:00
JIT: Add exhaustive pseudo-class and pseudo-element variant support (#4482)
* Add first-line, first-letter, and marker variants * Add selection variant Co-Authored-By: Eric Rodrigues Pires <eric@eric.dev.br> * Add remaining pseudo-class variants * Add target pseudo-class Co-Authored-By: Peter Neupauer <peter@neupauer.sk> * add test for parallel variants * implement parallel variants Co-authored-by: Eric Rodrigues Pires <eric@eric.dev.br> Co-authored-by: Peter Neupauer <peter@neupauer.sk> Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
This commit is contained in:
parent
8cd60171e0
commit
d1e9632064
@ -11,7 +11,55 @@ import {
|
||||
} from '../util/pluginUtils'
|
||||
|
||||
export default {
|
||||
pseudoClassVariants: function ({ config, addVariant }) {
|
||||
pseudoElementVariants: function ({ config, addVariant }) {
|
||||
addVariant(
|
||||
'first-letter',
|
||||
transformAllSelectors((selector) => {
|
||||
return updateAllClasses(selector, (className, { withPseudo }) => {
|
||||
return withPseudo(`first-letter${config('separator')}${className}`, '::first-letter')
|
||||
})
|
||||
})
|
||||
)
|
||||
|
||||
addVariant(
|
||||
'first-line',
|
||||
transformAllSelectors((selector) => {
|
||||
return updateAllClasses(selector, (className, { withPseudo }) => {
|
||||
return withPseudo(`first-line${config('separator')}${className}`, '::first-line')
|
||||
})
|
||||
})
|
||||
)
|
||||
|
||||
addVariant('marker', [
|
||||
transformAllSelectors((selector) => {
|
||||
let variantSelector = updateAllClasses(selector, (className) => {
|
||||
return `marker${config('separator')}${className}`
|
||||
})
|
||||
|
||||
return `${variantSelector} *::marker`
|
||||
}),
|
||||
transformAllSelectors((selector) => {
|
||||
return updateAllClasses(selector, (className, { withPseudo }) => {
|
||||
return withPseudo(`marker${config('separator')}${className}`, '::marker')
|
||||
})
|
||||
}),
|
||||
])
|
||||
|
||||
addVariant('selection', [
|
||||
transformAllSelectors((selector) => {
|
||||
let variantSelector = updateAllClasses(selector, (className) => {
|
||||
return `selection${config('separator')}${className}`
|
||||
})
|
||||
|
||||
return `${variantSelector} *::selection`
|
||||
}),
|
||||
transformAllSelectors((selector) => {
|
||||
return updateAllClasses(selector, (className, { withPseudo }) => {
|
||||
return withPseudo(`selection${config('separator')}${className}`, '::selection')
|
||||
})
|
||||
}),
|
||||
])
|
||||
|
||||
addVariant(
|
||||
'before',
|
||||
transformAllSelectors(
|
||||
@ -55,16 +103,40 @@ export default {
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
},
|
||||
pseudoClassVariants: function ({ config, addVariant }) {
|
||||
let pseudoVariants = [
|
||||
// Positional
|
||||
['first', 'first-child'],
|
||||
['last', 'last-child'],
|
||||
['only', 'only-child'],
|
||||
['odd', 'nth-child(odd)'],
|
||||
['even', 'nth-child(even)'],
|
||||
'first-of-type',
|
||||
'last-of-type',
|
||||
'only-of-type',
|
||||
|
||||
// State
|
||||
'visited',
|
||||
'target',
|
||||
|
||||
// Forms
|
||||
'default',
|
||||
'checked',
|
||||
'empty',
|
||||
'indeterminate',
|
||||
'placeholder-shown',
|
||||
'autofill',
|
||||
'required',
|
||||
'valid',
|
||||
'invalid',
|
||||
'in-range',
|
||||
'out-of-range',
|
||||
'read-only',
|
||||
|
||||
// Content
|
||||
'empty',
|
||||
|
||||
// Interactive
|
||||
'focus-within',
|
||||
'hover',
|
||||
'focus',
|
||||
|
||||
@ -100,7 +100,7 @@ function applyVariant(variant, matches, context) {
|
||||
}
|
||||
|
||||
if (context.variantMap.has(variant)) {
|
||||
let [variantSort, applyThisVariant] = context.variantMap.get(variant)
|
||||
let variantFunctionTuples = context.variantMap.get(variant)
|
||||
let result = []
|
||||
|
||||
for (let [{ sort, layer, options }, rule] of matches) {
|
||||
@ -112,36 +112,39 @@ function applyVariant(variant, matches, context) {
|
||||
let container = postcss.root()
|
||||
container.append(rule.clone())
|
||||
|
||||
function modifySelectors(modifierFunction) {
|
||||
container.each((rule) => {
|
||||
if (rule.type !== 'rule') {
|
||||
return
|
||||
}
|
||||
for (let [variantSort, variantFunction] of variantFunctionTuples) {
|
||||
let clone = container.clone()
|
||||
function modifySelectors(modifierFunction) {
|
||||
clone.each((rule) => {
|
||||
if (rule.type !== 'rule') {
|
||||
return
|
||||
}
|
||||
|
||||
rule.selectors = rule.selectors.map((selector) => {
|
||||
return modifierFunction({
|
||||
get className() {
|
||||
return getClassNameFromSelector(selector)
|
||||
},
|
||||
selector,
|
||||
rule.selectors = rule.selectors.map((selector) => {
|
||||
return modifierFunction({
|
||||
get className() {
|
||||
return getClassNameFromSelector(selector)
|
||||
},
|
||||
selector,
|
||||
})
|
||||
})
|
||||
})
|
||||
return clone
|
||||
}
|
||||
|
||||
let ruleWithVariant = variantFunction({
|
||||
container: clone,
|
||||
separator: context.tailwindConfig.separator,
|
||||
modifySelectors,
|
||||
})
|
||||
return container
|
||||
|
||||
if (ruleWithVariant === null) {
|
||||
continue
|
||||
}
|
||||
|
||||
let withOffset = [{ sort: variantSort | sort, layer, options }, clone.nodes[0]]
|
||||
result.push(withOffset)
|
||||
}
|
||||
|
||||
let ruleWithVariant = applyThisVariant({
|
||||
container,
|
||||
separator: context.tailwindConfig.separator,
|
||||
modifySelectors,
|
||||
})
|
||||
|
||||
if (ruleWithVariant === null) {
|
||||
continue
|
||||
}
|
||||
|
||||
let withOffset = [{ sort: variantSort | sort, layer, options }, container.nodes[0]]
|
||||
result.push(withOffset)
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
@ -13,6 +13,7 @@ import isPlainObject from '../../util/isPlainObject'
|
||||
import escapeClassName from '../../util/escapeClassName'
|
||||
import nameClass from '../../util/nameClass'
|
||||
import { coerceValue } from '../../util/pluginUtils'
|
||||
import bigSign from '../../util/bigSign'
|
||||
import corePlugins from '../corePlugins'
|
||||
import * as sharedState from './sharedState'
|
||||
import { env } from './sharedState'
|
||||
@ -152,9 +153,11 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs
|
||||
}
|
||||
|
||||
return {
|
||||
addVariant(variantName, applyThisVariant, options = {}) {
|
||||
addVariant(variantName, variantFunctions, options = {}) {
|
||||
variantFunctions = [].concat(variantFunctions)
|
||||
|
||||
insertInto(variantList, variantName, options)
|
||||
variantMap.set(variantName, applyThisVariant)
|
||||
variantMap.set(variantName, variantFunctions)
|
||||
},
|
||||
postcss,
|
||||
prefix: applyConfiguredPrefix,
|
||||
@ -395,7 +398,7 @@ function resolvePlugins(context, tailwindDirectives, root) {
|
||||
|
||||
// TODO: This is a workaround for backwards compatibility, since custom variants
|
||||
// were historically sorted before screen/stackable variants.
|
||||
let beforeVariants = [corePlugins['pseudoClassVariants']]
|
||||
let beforeVariants = [corePlugins['pseudoElementVariants'], corePlugins['pseudoClassVariants']]
|
||||
let afterVariants = [
|
||||
corePlugins['directionVariants'],
|
||||
corePlugins['reducedMotionVariants'],
|
||||
@ -445,17 +448,28 @@ function registerPlugins(plugins, context) {
|
||||
}
|
||||
|
||||
reservedBits += 3n
|
||||
context.variantOrder = variantList.reduce(
|
||||
(map, variant, i) => map.set(variant, (1n << BigInt(i)) << reservedBits),
|
||||
new Map()
|
||||
|
||||
let offset = 0
|
||||
context.variantOrder = new Map(
|
||||
variantList
|
||||
.map((variant, i) => {
|
||||
let variantFunctions = variantMap.get(variant).length
|
||||
let bits = (1n << BigInt(i + offset)) << reservedBits
|
||||
offset += variantFunctions - 1
|
||||
return [variant, bits]
|
||||
})
|
||||
.sort(([, a], [, z]) => bigSign(a - z))
|
||||
)
|
||||
|
||||
context.minimumScreen = [...context.variantOrder.values()].shift()
|
||||
|
||||
// Build variantMap
|
||||
for (let [variantName, variantFunction] of variantMap.entries()) {
|
||||
for (let [variantName, variantFunctions] of variantMap.entries()) {
|
||||
let sort = context.variantOrder.get(variantName)
|
||||
context.variantMap.set(variantName, [sort, variantFunction])
|
||||
context.variantMap.set(
|
||||
variantName,
|
||||
variantFunctions.map((variantFunction, idx) => [sort << BigInt(idx), variantFunction])
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
70
tests/jit/parallel-variants.test.js
Normal file
70
tests/jit/parallel-variants.test.js
Normal file
@ -0,0 +1,70 @@
|
||||
import postcss from 'postcss'
|
||||
import path from 'path'
|
||||
import tailwind from '../../src/jit/index.js'
|
||||
import { transformAllSelectors, updateAllClasses } from '../../src/util/pluginUtils.js'
|
||||
|
||||
function run(input, config = {}) {
|
||||
const { currentTestName } = expect.getState()
|
||||
|
||||
return postcss(tailwind(config)).process(input, {
|
||||
from: `${path.resolve(__filename)}?test=${currentTestName}`,
|
||||
})
|
||||
}
|
||||
|
||||
test('basic parallel variants', async () => {
|
||||
let config = {
|
||||
mode: 'jit',
|
||||
purge: [
|
||||
{
|
||||
raw: '<div class="font-normal hover:test:font-black test:font-bold test:font-medium"></div>',
|
||||
},
|
||||
],
|
||||
theme: {},
|
||||
plugins: [
|
||||
function test({ addVariant, config }) {
|
||||
addVariant('test', [
|
||||
transformAllSelectors((selector) => {
|
||||
let variantSelector = updateAllClasses(selector, (className) => {
|
||||
return `test${config('separator')}${className}`
|
||||
})
|
||||
|
||||
return `${variantSelector} *::test`
|
||||
}),
|
||||
transformAllSelectors((selector) => {
|
||||
return updateAllClasses(selector, (className, { withPseudo }) => {
|
||||
return withPseudo(`test${config('separator')}${className}`, '::test')
|
||||
})
|
||||
}),
|
||||
])
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
let css = `@tailwind utilities`
|
||||
|
||||
return run(css, config).then((result) => {
|
||||
expect(result.css).toMatchFormattedCss(`
|
||||
.font-normal {
|
||||
font-weight: 400;
|
||||
}
|
||||
.test\\:font-bold *::test {
|
||||
font-weight: 700;
|
||||
}
|
||||
.test\\:font-medium *::test {
|
||||
font-weight: 500;
|
||||
}
|
||||
.hover\\:test\\:font-black:hover *::test {
|
||||
font-weight: 900;
|
||||
}
|
||||
.test\\:font-bold::test {
|
||||
font-weight: 700;
|
||||
}
|
||||
.test\\:font-medium::test {
|
||||
font-weight: 500;
|
||||
}
|
||||
.hover\\:test\\:font-black:hover::test {
|
||||
font-weight: 900;
|
||||
}
|
||||
`)
|
||||
})
|
||||
})
|
||||
@ -13,10 +13,52 @@
|
||||
--tw-ring-offset-shadow: 0 0 #0000;
|
||||
--tw-ring-shadow: 0 0 #0000;
|
||||
}
|
||||
.shadow-md {
|
||||
--tw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
var(--tw-shadow);
|
||||
.first-letter\:text-2xl::first-letter {
|
||||
font-size: 1.5rem;
|
||||
line-height: 2rem;
|
||||
}
|
||||
.first-letter\:text-red-500::first-letter {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgba(239, 68, 68, var(--tw-text-opacity));
|
||||
}
|
||||
.first-line\:bg-yellow-300::first-line {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgba(252, 211, 77, var(--tw-bg-opacity));
|
||||
}
|
||||
.first-line\:underline::first-line {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.marker\:text-lg *::marker {
|
||||
font-size: 1.125rem;
|
||||
line-height: 1.75rem;
|
||||
}
|
||||
.marker\:text-red-500 *::marker {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgba(239, 68, 68, var(--tw-text-opacity));
|
||||
}
|
||||
.marker\:text-lg::marker {
|
||||
font-size: 1.125rem;
|
||||
line-height: 1.75rem;
|
||||
}
|
||||
.marker\:text-red-500::marker {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgba(239, 68, 68, var(--tw-text-opacity));
|
||||
}
|
||||
.selection\:bg-blue-500 *::selection {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgba(59, 130, 246, var(--tw-bg-opacity));
|
||||
}
|
||||
.selection\:text-white *::selection {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgba(255, 255, 255, var(--tw-text-opacity));
|
||||
}
|
||||
.selection\:bg-blue-500::selection {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgba(59, 130, 246, var(--tw-bg-opacity));
|
||||
}
|
||||
.selection\:text-white::selection {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgba(255, 255, 255, var(--tw-text-opacity));
|
||||
}
|
||||
.before\:block::before {
|
||||
content: '';
|
||||
@ -45,6 +87,11 @@
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
var(--tw-shadow);
|
||||
}
|
||||
.only\:shadow-md:only-child {
|
||||
--tw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
var(--tw-shadow);
|
||||
}
|
||||
.odd\:shadow-md:nth-child(odd) {
|
||||
--tw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
@ -55,17 +102,77 @@
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
var(--tw-shadow);
|
||||
}
|
||||
.first-of-type\:shadow-md:first-of-type {
|
||||
--tw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
var(--tw-shadow);
|
||||
}
|
||||
.last-of-type\:shadow-md:last-of-type {
|
||||
--tw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
var(--tw-shadow);
|
||||
}
|
||||
.only-of-type\:shadow-md:only-of-type {
|
||||
--tw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
var(--tw-shadow);
|
||||
}
|
||||
.visited\:shadow-md:visited {
|
||||
--tw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
var(--tw-shadow);
|
||||
}
|
||||
.target\:shadow-md:target {
|
||||
--tw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
var(--tw-shadow);
|
||||
}
|
||||
.default\:shadow-md:default {
|
||||
--tw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
var(--tw-shadow);
|
||||
}
|
||||
.checked\:shadow-md:checked {
|
||||
--tw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
var(--tw-shadow);
|
||||
}
|
||||
.empty\:shadow-md:empty {
|
||||
.indeterminate\:shadow-md:indeterminate {
|
||||
--tw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
var(--tw-shadow);
|
||||
}
|
||||
.placeholder-shown\:shadow-md:placeholder-shown {
|
||||
--tw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
var(--tw-shadow);
|
||||
}
|
||||
.autofill\:shadow-md:autofill {
|
||||
--tw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
var(--tw-shadow);
|
||||
}
|
||||
.required\:shadow-md:required {
|
||||
--tw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
var(--tw-shadow);
|
||||
}
|
||||
.valid\:shadow-md:valid {
|
||||
--tw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
var(--tw-shadow);
|
||||
}
|
||||
.invalid\:shadow-md:invalid {
|
||||
--tw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
var(--tw-shadow);
|
||||
}
|
||||
.in-range\:shadow-md:in-range {
|
||||
--tw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
var(--tw-shadow);
|
||||
}
|
||||
.out-of-range\:shadow-md:out-of-range {
|
||||
--tw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
var(--tw-shadow);
|
||||
@ -75,6 +182,11 @@
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
var(--tw-shadow);
|
||||
}
|
||||
.empty\:shadow-md:empty {
|
||||
--tw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
var(--tw-shadow);
|
||||
}
|
||||
.focus-within\:shadow-md:focus-within {
|
||||
--tw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
@ -120,6 +232,11 @@
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
var(--tw-shadow);
|
||||
}
|
||||
.group:only-child .group-only\:shadow-md {
|
||||
--tw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
var(--tw-shadow);
|
||||
}
|
||||
.group:nth-child(odd) .group-odd\:shadow-md {
|
||||
--tw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
@ -130,16 +247,91 @@
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
var(--tw-shadow);
|
||||
}
|
||||
.group:first-of-type .group-first-of-type\:shadow-md {
|
||||
--tw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
var(--tw-shadow);
|
||||
}
|
||||
.group:last-of-type .group-last-of-type\:shadow-md {
|
||||
--tw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
var(--tw-shadow);
|
||||
}
|
||||
.group:only-of-type .group-only-of-type\:shadow-md {
|
||||
--tw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
var(--tw-shadow);
|
||||
}
|
||||
.group:visited .group-visited\:shadow-md {
|
||||
--tw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
var(--tw-shadow);
|
||||
}
|
||||
.group:target .group-target\:shadow-md {
|
||||
--tw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
var(--tw-shadow);
|
||||
}
|
||||
.group:default .group-default\:shadow-md {
|
||||
--tw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
var(--tw-shadow);
|
||||
}
|
||||
.group:checked .group-checked\:shadow-md {
|
||||
--tw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
var(--tw-shadow);
|
||||
}
|
||||
.group:indeterminate .group-indeterminate\:shadow-md {
|
||||
--tw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
var(--tw-shadow);
|
||||
}
|
||||
.group:placeholder-shown .group-placeholder-shown\:shadow-md {
|
||||
--tw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
var(--tw-shadow);
|
||||
}
|
||||
.group:autofill .group-autofill\:shadow-md {
|
||||
--tw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
var(--tw-shadow);
|
||||
}
|
||||
.group:required .group-required\:shadow-md {
|
||||
--tw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
var(--tw-shadow);
|
||||
}
|
||||
.group:valid .group-valid\:shadow-md {
|
||||
--tw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
var(--tw-shadow);
|
||||
}
|
||||
.group:invalid .group-invalid\:shadow-md {
|
||||
--tw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
var(--tw-shadow);
|
||||
}
|
||||
.group:in-range .group-in-range\:shadow-md {
|
||||
--tw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
var(--tw-shadow);
|
||||
}
|
||||
.group:out-of-range .group-out-of-range\:shadow-md {
|
||||
--tw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
var(--tw-shadow);
|
||||
}
|
||||
.group:read-only .group-read-only\:shadow-md {
|
||||
--tw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
var(--tw-shadow);
|
||||
}
|
||||
.group:empty .group-empty\:shadow-md {
|
||||
--tw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
var(--tw-shadow);
|
||||
}
|
||||
.group:focus-within .group-focus-within\:shadow-md {
|
||||
--tw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
|
||||
@ -9,41 +9,74 @@
|
||||
</head>
|
||||
<body>
|
||||
<!-- Basic pseudo variants -->
|
||||
<div class="shadow-md"></div>
|
||||
<div class="first:shadow-md"></div>
|
||||
<div class="last:shadow-md"></div>
|
||||
<div class="only:shadow-md"></div>
|
||||
<div class="even:shadow-md"></div>
|
||||
<div class="odd:shadow-md"></div>
|
||||
<div class="first-of-type:shadow-md"></div>
|
||||
<div class="last-of-type:shadow-md"></div>
|
||||
<div class="only-of-type:shadow-md"></div>
|
||||
<div class="hover:shadow-md"></div>
|
||||
<div class="focus:shadow-md"></div>
|
||||
<div class="disabled:shadow-md"></div>
|
||||
<div class="active:shadow-md"></div>
|
||||
<div class="first:shadow-md"></div>
|
||||
<div class="last:shadow-md"></div>
|
||||
<div class="even:shadow-md"></div>
|
||||
<div class="odd:shadow-md"></div>
|
||||
<div class="target:shadow-md"></div>
|
||||
<div class="visited:shadow-md"></div>
|
||||
<div class="default:shadow-md"></div>
|
||||
<div class="checked:shadow-md"></div>
|
||||
<div class="indeterminate:shadow-md"></div>
|
||||
<div class="placeholder-shown:shadow-md"></div>
|
||||
<div class="autofill:shadow-md"></div>
|
||||
<div class="focus-within:shadow-md"></div>
|
||||
<div class="focus-visible:shadow-md"></div>
|
||||
<div class="empty:shadow-md"></div>
|
||||
<div class="required:shadow-md"></div>
|
||||
<div class="valid:shadow-md"></div>
|
||||
<div class="invalid:shadow-md"></div>
|
||||
<div class="in-range:shadow-md"></div>
|
||||
<div class="out-of-range:shadow-md"></div>
|
||||
<div class="read-only:shadow-md"></div>
|
||||
<div class="empty:shadow-md"></div>
|
||||
|
||||
<!-- Pseudo-element variants -->
|
||||
<div class="first-letter:text-red-500 first-letter:text-2xl"></div>
|
||||
<div class="first-line:underline first-line:bg-yellow-300"></div>
|
||||
<ul>
|
||||
<li class="marker:text-red-500 marker:text-lg"></li>
|
||||
</ul>
|
||||
<div class="selection:bg-blue-500 selection:text-white"></div>
|
||||
<div class="before:block before:bg-red-500"></div>
|
||||
<div class="after:flex after:uppercase"></div>
|
||||
|
||||
<!-- Group variants -->
|
||||
<div class="group-first:shadow-md"></div>
|
||||
<div class="group-last:shadow-md"></div>
|
||||
<div class="group-only:shadow-md"></div>
|
||||
<div class="group-even:shadow-md"></div>
|
||||
<div class="group-odd:shadow-md"></div>
|
||||
<div class="group-first-of-type:shadow-md"></div>
|
||||
<div class="group-last-of-type:shadow-md"></div>
|
||||
<div class="group-only-of-type:shadow-md"></div>
|
||||
<div class="group-hover:shadow-md"></div>
|
||||
<div class="group-focus:shadow-md"></div>
|
||||
<div class="group-disabled:shadow-md"></div>
|
||||
<div class="group-active:shadow-md"></div>
|
||||
<div class="group-first:shadow-md"></div>
|
||||
<div class="group-last:shadow-md"></div>
|
||||
<div class="group-even:shadow-md"></div>
|
||||
<div class="group-odd:shadow-md"></div>
|
||||
<div class="group-odd:shadow-md"></div>
|
||||
<div class="group-target:shadow-md"></div>
|
||||
<div class="group-visited:shadow-md"></div>
|
||||
<div class="group-default:shadow-md"></div>
|
||||
<div class="group-checked:shadow-md"></div>
|
||||
<div class="group-indeterminate:shadow-md"></div>
|
||||
<div class="group-placeholder-shown:shadow-md"></div>
|
||||
<div class="group-autofill:shadow-md"></div>
|
||||
<div class="group-focus-within:shadow-md"></div>
|
||||
<div class="group-focus-visible:shadow-md"></div>
|
||||
<div class="group-focus-visible:shadow-md"></div>
|
||||
<div class="group-required:shadow-md"></div>
|
||||
<div class="group-valid:shadow-md"></div>
|
||||
<div class="group-invalid:shadow-md"></div>
|
||||
<div class="group-in-range:shadow-md"></div>
|
||||
<div class="group-out-of-range:shadow-md"></div>
|
||||
<div class="group-read-only:shadow-md"></div>
|
||||
<div class="group-empty:shadow-md"></div>
|
||||
|
||||
<!-- Reduced motion variants -->
|
||||
<div class="motion-safe:shadow-md"></div>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user