diff --git a/packages/calcite-components/src/components/accordion-item/accordion-item.e2e.ts b/packages/calcite-components/src/components/accordion-item/accordion-item.e2e.ts index 00e7d5432a6..7e97b524020 100644 --- a/packages/calcite-components/src/components/accordion-item/accordion-item.e2e.ts +++ b/packages/calcite-components/src/components/accordion-item/accordion-item.e2e.ts @@ -1,5 +1,5 @@ import { newE2EPage } from "@stencil/core/testing"; -import { accessible, renders, slots, hidden, focusable } from "../../tests/commonTests"; +import { accessible, renders, slots, hidden, themed, focusable } from "../../tests/commonTests"; import { html } from "../../../support/formatting"; import { CSS, IDS, SLOTS } from "./resources"; @@ -24,6 +24,67 @@ describe("calcite-accordion-item", () => { focusable("calcite-accordion-item"); }); + describe("theme", () => { + describe("default", () => { + themed( + html`content`, + { + "--calcite-accordion-text-color": [ + { + shadowSelector: `.${CSS.content}`, + targetProp: "color", + }, + { + shadowSelector: `.${CSS.expandIcon}`, + targetProp: "color", + }, + { + shadowSelector: `.${CSS.description}`, + targetProp: "color", + }, + ], + "--calcite-accordion-text-color-hover": [ + { + shadowSelector: `.${CSS.heading}`, + targetProp: "color", + }, + ], + "--calcite-accordion-border-color": [ + { + shadowSelector: `.${CSS.content}`, + targetProp: "borderBlockEndColor", + }, + { + shadowSelector: `.${CSS.header}`, + targetProp: "borderBlockEndColor", + }, + ], + }, + ); + }); + describe("expanded", () => { + themed( + html`content`, + { + "--calcite-accordion-text-color-hover": [ + { + shadowSelector: `.${CSS.description}`, + targetProp: "color", + }, + ], + "--calcite-accordion-text-color-pressed": { + shadowSelector: `.${CSS.heading}`, + targetProp: "color", + }, + }, + ); + }); + }); + it("properly uses ARIA and roles", async () => { // this test covers a11y relationships not reported by axe-core/accessible test helper diff --git a/packages/calcite-components/src/components/accordion-item/accordion-item.scss b/packages/calcite-components/src/components/accordion-item/accordion-item.scss index ef7a20c7e15..2d2d86fb2a9 100644 --- a/packages/calcite-components/src/components/accordion-item/accordion-item.scss +++ b/packages/calcite-components/src/components/accordion-item/accordion-item.scss @@ -1,194 +1,199 @@ +/** + * CSS Custom Properties + * + * These properties can be overridden using the component's tag as selector. + * + * @prop --calcite-accordion-border-color: Specifies the component's border color. + * @prop --calcite-accordion-item-space: Specifies the component's padding. + * @prop --calcite-accordion-text-color: Specifies the component's text color. + * @prop --calcite-accordion-text-color-hover: Specifies the component's main text color on hover. + * @prop --calcite-accordion-text-color-pressed: Specifies the component's main text color when pressed. + */ + %icon-position { /* icon rotation variables */ - --calcite-accordion-item-icon-rotation: calc(theme("rotate.90") * -1); - --calcite-accordion-item-active-icon-rotation: theme("rotate.0"); - --calcite-accordion-item-icon-rotation-rtl: theme("rotate.90"); - --calcite-accordion-item-active-icon-rotation-rtl: theme("rotate.0"); + --calcite-internal-accordion-item-icon-rotation: calc(theme("rotate.90") * -1); + --calcite-internal-accordion-item-active-icon-rotation: theme("rotate.0"); + --calcite-internal-accordion-item-icon-rotation-rtl: theme("rotate.90"); + --calcite-internal-accordion-item-active-icon-rotation-rtl: theme("rotate.0"); +} + +:host { + @apply relative + flex + flex-col + no-underline; + + color: var(--calcite-accordion-text-color, var(--calcite-color-text-3)); + border-width: 0; } // icon position variants for child .icon-position--start { @extend %icon-position; - --calcite-accordion-item-flex-direction: row-reverse; - --calcite-accordion-item-icon-spacing-start: 0; - --calcite-accordion-item-icon-spacing-end: var(--calcite-accordion-icon-margin); + --calcite-internal-accordion-item-flex-direction: row-reverse; + --calcite-internal-accordion-item-icon-spacing-start: 0; + --calcite-internal-accordion-item-icon-spacing-end: var(--calcite-internal-accordion-icon-margin); } .icon-position--end { @extend %icon-position; - --calcite-accordion-item-flex-direction: row; - --calcite-accordion-item-icon-spacing-start: var(--calcite-accordion-icon-margin); - --calcite-accordion-item-icon-spacing-end: 0; + --calcite-internal-accordion-item-flex-direction: row; + --calcite-internal-accordion-item-icon-spacing-start: var(--calcite-internal-accordion-icon-margin); + --calcite-internal-accordion-item-icon-spacing-end: 0; } .icon-position--end:not(.icon-type--plus-minus) { - --calcite-accordion-item-icon-rotation: theme("rotate.0"); - --calcite-accordion-item-active-icon-rotation: theme("rotate.180"); - --calcite-accordion-item-icon-rotation-rtl: theme("rotate.0"); - --calcite-accordion-item-active-icon-rotation-rtl: calc(theme("rotate.180") * -1); + --calcite-internal-accordion-item-icon-rotation: theme("rotate.0"); + --calcite-internal-accordion-item-active-icon-rotation: theme("rotate.180"); + --calcite-internal-accordion-item-icon-rotation-rtl: theme("rotate.0"); + --calcite-internal-accordion-item-active-icon-rotation-rtl: calc(theme("rotate.180") * -1); } -:host { - @apply text-color-3 - relative - flex - flex-col - no-underline; - background-color: var(--calcite-accordion-item-background, theme("backgroundColor.foreground.1")); +// .header / content +.content, +.header { + border-block-end-width: var(--calcite-border-width-sm); + border-block-end-style: solid; + border-color: var(--calcite-accordion-border-color, theme("borderColor.color.2")); } -// focus styles -.header-content { - @apply focus-base; +.header-content, +.content { + padding: var( + --calcite-accordion-item-space, + var( + --calcite-internal-accordion-item-padding, + var(--calcite-internal-accordion-item-spacing-unit, theme("spacing.2") 0.75rem) + ) + ); } -.header-content:focus { - @apply focus-inset; -} +.header { + @apply flex items-stretch; -:host([expanded]) { - @apply text-color-1; - & .content { - @apply text-color-1 block; - } - & .header { - border-block-end-color: transparent; + * { + @apply inline-flex + items-center + duration-150 + ease-in-out; + @include word-break(); } } -// .header / content -.header { - @apply flex items-stretch; -} +.header-content { + @apply focus-base flex-grow cursor-pointer; + flex-direction: var(--calcite-internal-accordion-item-flex-direction); -.icon { - @apply text-color-3 - relative - m-0 - inline-flex - duration-150 - ease-in-out; - margin-inline-end: var(--calcite-accordion-item-icon-spacing-start); - margin-inline-start: var(--calcite-accordion-item-icon-spacing-end); -} + &:focus { + @apply focus-inset; + } -.icon--start { - @apply flex items-center; - margin-inline-end: var(--calcite-accordion-icon-margin); -} + &:focus, + &:hover, + &:active { + color: var(--calcite-accordion-text-color-hover, var(--calcite-color-text-2)); -.icon--end { - @apply flex items-center; - margin-inline-end: var(--calcite-accordion-icon-margin); - margin-inline-start: var(--calcite-accordion-icon-margin); + .expand-icon, + .heading { + color: var(--calcite-accordion-text-color-pressed, var(--calcite-color-text-1)); + } + } } .header-container { inline-size: 100%; } -.content { - padding: var(--calcite-accordion-item-padding); +// accordion item title +.header-text { + @apply my-0 flex-grow flex-col py-0; + text-align: initial; + margin-inline-end: theme("margin.auto"); } -.content, -.header { - border-block-end: 1px solid var(--calcite-accordion-item-border, theme("borderColor.color.2")); +.heading, +.description { + @apply flex w-full; } -.header * { - @apply inline-flex - items-center - duration-150 - ease-in-out; - @include word-break(); +.heading { + @apply font-medium; } -.content { - @apply text-color-3 hidden pt-0; - text-align: initial; +.actions-start, +.actions-end { + @apply flex items-center; } -// accordion item icon -.expand-icon { - @apply text-color-3; - margin-inline-start: var(--calcite-accordion-item-icon-spacing-start); - margin-inline-end: var(--calcite-accordion-item-icon-spacing-end); - transform: rotate(var(--calcite-accordion-item-icon-rotation)); -} +.icon { + @apply duration-150 + ease-in-out + flex + items-center; -.calcite--rtl .expand-icon { - transform: rotate(var(--calcite-accordion-item-icon-rotation-rtl)); + margin-inline-end: var(--calcite-internal-accordion-item-icon-spacing-start); + margin-inline-start: var(--calcite-internal-accordion-item-icon-spacing-end); } -:host([expanded]) .expand-icon { - @apply text-color-3; - transform: rotate(var(--calcite-accordion-item-active-icon-rotation)); +.icon--start { + margin-inline-end: var(--calcite-internal-accordion-icon-margin); } -:host([expanded]) .calcite--rtl .expand-icon { - transform: rotate(var(--calcite-accordion-item-active-icon-rotation-rtl)); +.icon--end { + margin-inline-end: var(--calcite-internal-accordion-icon-margin); + margin-inline-start: var(--calcite-internal-accordion-icon-margin); } -// accordion item title -.header-text { - @apply my-0 flex-grow flex-col py-0; - text-align: initial; - margin-inline-end: theme("margin.auto"); +// accordion item icon +.expand-icon { + color: var(--calcite-accordion-text-color, var(--calcite-color-text-3)); + margin-inline-start: var(--calcite-internal-accordion-item-icon-spacing-start); + margin-inline-end: var(--calcite-internal-accordion-item-icon-spacing-end); + transform: rotate(var(--calcite-internal-accordion-item-icon-rotation)); } -.heading, -.description { - @apply flex w-full; +.calcite--rtl .expand-icon { + transform: rotate(var(--calcite-internal-accordion-item-icon-rotation-rtl)); } -.heading { - @apply text-color-2 font-medium; -} .description { - @apply text-color-3 mt-1; + @apply mt-1; } -.header-content:focus, -.header-content:hover { - & .heading { - @apply text-color-1; - } - & .icon { - @apply text-color-1; - } +.content { + @apply hidden pt-0; + text-align: initial; +} - & .expand-icon { - @apply text-color-1; - } - & .description { - @apply text-color-2; +:host(:not(:focus):not(:hover):not([expanded])) { + .heading { + color: var(--calcite-accordion-text-color-hover, var(--calcite-color-text-2)); } } -.header-content:focus, -.header-content:active, :host([expanded]) { - & .heading { - @apply text-color-1; + color: var(--calcite-accordion-text-color-pressed, var(--calcite-color-text-1)); + + .header { + border-block-end-color: transparent; } - & .icon { - @apply text-color-1; + + .expand-icon { + color: var(--calcite-accordion-text-color-hover, var(--calcite-color-text-2)); + transform: rotate(var(--calcite-internal-accordion-item-active-icon-rotation)); } - & .description { - @apply text-color-2; + .calcite--rtl .expand-icon { + transform: rotate(var(--calcite-internal-accordion-item-active-icon-rotation-rtl)); } -} -.header-content { - @apply flex-grow cursor-pointer; - padding: var(--calcite-accordion-item-padding); - flex-direction: var(--calcite-accordion-item-flex-direction); -} + .description { + color: var(--calcite-accordion-text-color-hover, var(--calcite-color-text-2)); + } -.actions-start, -.actions-end { - @apply flex items-center; + .content { + @apply block; + } } @media (forced-colors: active) { diff --git a/packages/calcite-components/src/components/accordion-item/accordion-item.tsx b/packages/calcite-components/src/components/accordion-item/accordion-item.tsx index 936fcf062ef..b45259e2a17 100644 --- a/packages/calcite-components/src/components/accordion-item/accordion-item.tsx +++ b/packages/calcite-components/src/components/accordion-item/accordion-item.tsx @@ -163,7 +163,7 @@ export class AccordionItem implements ConditionalSlotComponent, LoadableComponen const dir = getElementDir(this.el); const iconStartEl = this.iconStart ? ( { const accordionContent = html` @@ -125,9 +126,9 @@ describe("calcite-accordion", () => { Accordion Item Content `); - const icon1 = await page.find(`calcite-accordion-item[id='1'] >>> .${CSS.iconStart}`); - const icon2 = await page.find(`calcite-accordion-item[id='2'] >>> .${CSS.iconStart}`); - const icon3 = await page.find(`calcite-accordion-item[id='3'] >>> .${CSS.iconStart}`); + const icon1 = await page.find(`calcite-accordion-item[id='1'] >>> .${ACCORDION_ITEM_CSS.iconStart}`); + const icon2 = await page.find(`calcite-accordion-item[id='2'] >>> .${ACCORDION_ITEM_CSS.iconStart}`); + const icon3 = await page.find(`calcite-accordion-item[id='3'] >>> .${ACCORDION_ITEM_CSS.iconStart}`); expect(icon1).not.toBe(null); expect(icon2).toBe(null); expect(icon3).not.toBe(null); @@ -142,7 +143,7 @@ describe("calcite-accordion", () => { const element = await page.find("calcite-accordion"); const [item1, item2, item3] = await element.findAll("calcite-accordion-item"); const [item1Content, item2Content, item3Content] = await element.findAll( - `calcite-accordion-item >>> .${CSS.content}`, + `calcite-accordion-item >>> .${ACCORDION_ITEM_CSS.content}`, ); expect(item1).not.toHaveAttribute("expanded"); @@ -166,7 +167,7 @@ describe("calcite-accordion", () => { expect(element).toEqualAttribute("selection-mode", "multiple"); const [item1, item2, item3] = await element.findAll("calcite-accordion-item"); const [item1Content, item2Content, item3Content] = await element.findAll( - `calcite-accordion-item >>> .${CSS.content}`, + `calcite-accordion-item >>> .${ACCORDION_ITEM_CSS.content}`, ); await item1.click(); await item3.click(); @@ -191,7 +192,7 @@ describe("calcite-accordion", () => { expect(element).toEqualAttribute("selection-mode", "single"); const [item1, item2, item3] = await element.findAll("calcite-accordion-item"); const [item1Content, item2Content, item3Content] = await element.findAll( - `calcite-accordion-item >>> .${CSS.content}`, + `calcite-accordion-item >>> .${ACCORDION_ITEM_CSS.content}`, ); await item1.click(); await item3.click(); @@ -240,7 +241,7 @@ describe("calcite-accordion", () => { expect(element).toEqualAttribute("selection-mode", "single-persist"); const [item1, item2, item3] = await element.findAll("calcite-accordion-item"); const [item1Content, item2Content, item3Content] = await element.findAll( - `calcite-accordion-item >>> .${CSS.content}`, + `calcite-accordion-item >>> .${ACCORDION_ITEM_CSS.content}`, ); await item2.click(); @@ -267,7 +268,7 @@ describe("calcite-accordion", () => { await page.waitForChanges(); const [item1, item2, item3] = await element.findAll("calcite-accordion-item"); const [item1Content, item2Content, item3Content] = await element.findAll( - `calcite-accordion-item >>> .${CSS.content}`, + `calcite-accordion-item >>> .${ACCORDION_ITEM_CSS.content}`, ); await item1.click(); await item3.click(); @@ -281,4 +282,17 @@ describe("calcite-accordion", () => { expect(await item2Content.isVisible()).toBe(true); expect(await item3Content.isVisible()).toBe(true); }); + + describe("theme", () => { + themed(`${accordionContent}`, { + "--calcite-accordion-background-color": { + shadowSelector: `.${CSS.accordion}`, + targetProp: "backgroundColor", + }, + "--calcite-accordion-border-color": { + shadowSelector: `.${CSS.accordion}`, + targetProp: "borderColor", + }, + }); + }); }); diff --git a/packages/calcite-components/src/components/accordion/accordion.scss b/packages/calcite-components/src/components/accordion/accordion.scss index 896e5da332a..5f390cb0b05 100644 --- a/packages/calcite-components/src/components/accordion/accordion.scss +++ b/packages/calcite-components/src/components/accordion/accordion.scss @@ -1,41 +1,51 @@ -// scale variants for child -:host([scale="s"]) { - --calcite-accordion-item-spacing-unit: theme("spacing.1"); - --calcite-accordion-icon-margin: theme("spacing.2"); - --calcite-accordion-item-padding: var(--calcite-accordion-item-spacing-unit) theme("spacing.2"); - @apply text-n2h; -} - -:host([scale="m"]) { - --calcite-accordion-item-spacing-unit: theme("spacing.2"); - --calcite-accordion-icon-margin: theme("spacing.3"); - --calcite-accordion-item-padding: var(--calcite-accordion-item-spacing-unit) theme("spacing.3"); - @apply text-n1h; -} - -:host([scale="l"]) { - --calcite-accordion-item-spacing-unit: theme("spacing.3"); - --calcite-accordion-icon-margin: theme("spacing.4"); - --calcite-accordion-item-padding: var(--calcite-accordion-item-spacing-unit) theme("spacing.4"); - @apply text-0h; -} +/** + * CSS Custom Properties + * + * These properties can be overridden using the component's tag as selector. + * + * @prop --calcite-accordion-border-color: Specifies the component's border color. + * @prop --calcite-accordion-background-color: Specifies the component's background color. +*/ :host { @apply relative block max-w-full leading-6; - --calcite-accordion-item-border: theme("borderColor.color.2"); - --calcite-accordion-item-background: theme("backgroundColor.foreground.1"); +} + +.accordion { + @apply border border-solid border-b-0; + border-color: var(--calcite-accordion-border-color, theme("borderColor.color.2")); + background-color: var(--calcite-accordion-background-color, theme("backgroundColor.foreground.1")); } .accordion--transparent { - --calcite-accordion-item-border: transparent; - --calcite-accordion-item-background: transparent; + --calcite-accordion-border-color: transparent; + border-color: var(--calcite-color-transparent); + background-color: var(--calcite-color-transparent); } -.accordion { - @apply border border-solid border-color-2 border-b-0; +// scale variants for child +:host([scale="s"]) { + --calcite-internal-accordion-item-spacing-unit: theme("spacing.1"); + --calcite-internal-accordion-icon-margin: theme("spacing.2"); + --calcite-internal-accordion-item-padding: var(--calcite-internal-accordion-item-spacing-unit) theme("spacing.2"); + @apply text-n2h; +} + +:host([scale="m"]) { + --calcite-internal-accordion-item-spacing-unit: theme("spacing.2"); + --calcite-internal-accordion-icon-margin: theme("spacing.3"); + --calcite-internal-accordion-item-padding: var(--calcite-internal-accordion-item-spacing-unit) theme("spacing.3"); + @apply text-n1h; +} + +:host([scale="l"]) { + --calcite-internal-accordion-item-spacing-unit: theme("spacing.3"); + --calcite-internal-accordion-icon-margin: theme("spacing.4"); + --calcite-internal-accordion-item-padding: var(--calcite-internal-accordion-item-spacing-unit) theme("spacing.4"); + @apply text-0h; } @include base-component(); diff --git a/packages/calcite-components/src/components/accordion/accordion.stories.ts b/packages/calcite-components/src/components/accordion/accordion.stories.ts index 122990c1642..583f21efba3 100644 --- a/packages/calcite-components/src/components/accordion/accordion.stories.ts +++ b/packages/calcite-components/src/components/accordion/accordion.stories.ts @@ -1,9 +1,11 @@ +// import { getVariableTestValue } from "../../tests/utils"; import { AccordionItem } from "../accordion-item/accordion-item"; import { modesDarkDefault } from "../../../.storybook/utils"; import { placeholderImage } from "../../../.storybook/placeholderImage"; import { iconNames } from "../../../.storybook/helpers"; import { html } from "../../../support/formatting"; import { ATTRIBUTES } from "../../../.storybook/resources"; +import { setCSSVariables } from "../../tests/utils/cssTokenValues"; import { Accordion } from "./accordion"; const { scale, appearance, selectionMode } = ATTRIBUTES; @@ -216,3 +218,47 @@ const accordionItemsIconHeaderUseCases = iconHeaderUseCasesArr export const longHeading_MediumIconForLargeAccordionItem_TestOnly = (): string => html` ${accordionItemsIconHeaderUseCases} `; + +export const theming_TestOnly = (): string => + html` +
+ + + ${accordionItemContent} + + + ${accordionItemContent} + + + ${accordionItemContent} + + + ${accordionItemContent} + + +
+ + + ${accordionItemContent} + + + ${accordionItemContent} + + + ${accordionItemContent} + + + ${accordionItemContent} + + +
`; diff --git a/packages/calcite-components/src/components/accordion/accordion.tsx b/packages/calcite-components/src/components/accordion/accordion.tsx index 847c944d861..98c8fbe9358 100644 --- a/packages/calcite-components/src/components/accordion/accordion.tsx +++ b/packages/calcite-components/src/components/accordion/accordion.tsx @@ -12,6 +12,7 @@ import { import { Appearance, Position, IconType, Scale, SelectionMode } from "../interfaces"; import { createObserver } from "../../utils/observers"; import { RequestedItem } from "./interfaces"; +import { CSS } from "./resources"; /** * @slot - A slot for adding `calcite-accordion-item`s. `calcite-accordion` cannot be nested, however `calcite-accordion-item`s can. */ @@ -93,8 +94,8 @@ export class Accordion { return (
diff --git a/packages/calcite-components/src/components/accordion/resources.ts b/packages/calcite-components/src/components/accordion/resources.ts new file mode 100644 index 00000000000..a09df2575b4 --- /dev/null +++ b/packages/calcite-components/src/components/accordion/resources.ts @@ -0,0 +1,4 @@ +export const CSS = { + accordion: "accordion", + transparent: "accordion--transparent", +}; diff --git a/packages/calcite-components/src/demos/_assets/demo-theme.ts b/packages/calcite-components/src/demos/_assets/demo-theme.ts index 55c02899401..06850cacfeb 100644 --- a/packages/calcite-components/src/demos/_assets/demo-theme.ts +++ b/packages/calcite-components/src/demos/_assets/demo-theme.ts @@ -9,12 +9,12 @@ export function getTokenValue(token: string): string { const tokenValueMap = { background$: "rgb(252, 244, 52)", - "text-color$": "rgb(239,118,39)", + "text-color$": "rgb(239, 118, 39)", "border-color$": "rgb(156, 89, 209)", - "background-color$": "rgb(44, 44, 44)", + "background-color$": "rgb(252, 244, 52)", color$: "rgb(0, 191, 255)", - highlighted$: "rgb(255, 105, 180)", - selected$: "rgb(255, 255, 255)", + hover$: "rgb(255, 105, 180)", + pressed$: "rgb(44, 44, 44)", shadow$: "rgb(255, 255, 255) 0px 0px 0px 4px, rgb(255, 105, 180) 0px 0px 0px 5px inset, rgb(0, 191, 255) 0px 0px 0px 9px", "z-index$": "42", diff --git a/packages/calcite-components/src/demos/accordion.html b/packages/calcite-components/src/demos/accordion.html index 72013ee02bb..212312cc7d3 100644 --- a/packages/calcite-components/src/demos/accordion.html +++ b/packages/calcite-components/src/demos/accordion.html @@ -904,6 +904,126 @@

Accordion

+ + + +
+
Theme
+ +
+ + + + + + + + + + + + Yes + No + + + +
+ +
+ + + + + + + + + + + + Yes + No + + + +
+ +
+ + + + + + + + + + + + Yes + No + + + +
+
+
diff --git a/packages/calcite-components/src/tests/utils/cssTokenValues.ts b/packages/calcite-components/src/tests/utils/cssTokenValues.ts index e5e34dd3ad2..0be2d52eba8 100644 --- a/packages/calcite-components/src/tests/utils/cssTokenValues.ts +++ b/packages/calcite-components/src/tests/utils/cssTokenValues.ts @@ -9,12 +9,12 @@ export function getTokenValue(token: string): string { const tokenValueMap = { background$: "rgb(252, 244, 52)", - "text-color$": "rgb(239,118,39)", + "text-color$": "rgb(239, 118, 39)", "border-color$": "rgb(156, 89, 209)", - "background-color$": "rgb(44, 44, 44)", + "background-color$": "rgb(252, 244, 52)", color$: "rgb(0, 191, 255)", - highlighted$: "rgb(255, 105, 180)", - selected$: "rgb(255, 255, 255)", + hover$: "rgb(255, 105, 180)", + pressed$: "rgb(44, 44, 44)", shadow$: "rgb(255, 255, 255) 0px 0px 0px 4px, rgb(255, 105, 180) 0px 0px 0px 5px inset, rgb(0, 191, 255) 0px 0px 0px 9px", "z-index$": "42",