/
githubmirror
/
gutenberg
Обзор
Документация
Войти
/
githubmirror
/
gutenberg
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
trunk
packages/components/src/button/style.scss
384 строки
9 KB
Lena Morita
Button: Suppress UA focus ring when focused and pressed (#81113)
04 авг 2026, 15:22
Не верифицирован
04 авг 2026, 15:22
582db9f
Код
Авторство
О чём код?
@use "sass:color"; @use "@wordpress/base-styles/colors" as *; @use "@wordpress/base-styles/mixins"; @use "@wordpress/base-styles/variables" as *; @use "../utils/theme-variables" as *; /** * For easier testing of potential regressions, you can use a Button variant matrix * available in a special Storybook instance by running `npm run storybook:e2e:dev`. * * @see https://github.com/WordPress/gutenberg/blob/trunk/test/storybook-playwright/README.md */ .components-button { // Defend against a conflicting focus ring from WordPress common.css on `a:focus`. &:focus:is(a) { box-shadow: none; } &:focus { outline: none; } &:focus:not(:active) { @include mixins.outset-ring__focus(); } display: inline-flex; text-decoration: none; font-family: inherit; font-size: $default-font-size; font-weight: var(--wpds-typography-font-weight-emphasis); margin: 0; cursor: var(--wpds-cursor-control); appearance: none; background: none; height: $button-size; align-items: center; box-sizing: border-box; padding: 4px 12px; // Allows 32px min-height. border-radius: $radius-small; color: $components-color-foreground; // Every variant reserves a 1px border (transparent by default) so the box // size stays identical whether or not a variant paints a visible border. border: $border-width solid transparent; &.is-next-40px-default-size { height: $button-size-next-default-40px; } &[aria-expanded="true"], &:hover:not(:disabled, [aria-disabled="true"]) { color: $components-color-accent; } /** * Primary button style. */ &.is-primary { white-space: nowrap; background: $components-color-accent; color: $components-color-accent-inverted; text-decoration: none; text-shadow: none; &:hover:not(:disabled) { background: $components-color-accent-darker-10; color: $components-color-accent-inverted; } &:active:not(:disabled) { background: $components-color-accent-darker-20; color: $components-color-accent-inverted; } &:disabled, &:disabled:active:enabled, &[aria-disabled="true"], &[aria-disabled="true"]:enabled, // This catches a situation where a Button is aria-disabled, but not disabled. &[aria-disabled="true"]:active:enabled { // TODO: Prepare for theming (https://github.com/WordPress/gutenberg/pull/45466/files#r1030872724) color: rgba($white, 0.4); background: $components-color-accent; } &.is-busy, &.is-busy:disabled, &.is-busy[aria-disabled="true"] { color: $components-color-accent-inverted; background-size: 100px 100%; /* stylelint-disable -- Disable reason: This function call looks nicer when each argument is on its own line. */ background-image: linear-gradient( -45deg, $components-color-accent 33%, $components-color-accent-darker-20 33%, $components-color-accent-darker-20 70%, $components-color-accent 70% ); /* stylelint-enable */ } } /** * Secondary and tertiary buttons. */ &.is-secondary, &.is-tertiary { &:disabled, &[aria-disabled="true"], &[aria-disabled="true"]:hover { color: $gray-600; background: transparent; transform: none; } } /** * Secondary button style. */ &.is-secondary { @media not ( prefers-reduced-motion ) { transition: border-color 0.1s linear; } border-color: $components-color-accent; white-space: nowrap; color: $components-color-accent; background: transparent; &:active:not(:disabled) { // Hide the border while pressed, keeping its width to avoid a size shift. border-color: transparent; } &:hover:not(:disabled, [aria-disabled="true"], .is-pressed) { border-color: $components-color-accent-darker-20; color: $components-color-accent-darker-20; background: color-mix(in srgb, $components-color-accent 4%, transparent); } &:focus:not(:active) { border-color: $components-color-accent; } &:disabled:not(:focus), &[aria-disabled="true"]:not(:focus), &[aria-disabled="true"]:hover:not(:focus) { border-color: var(--wpds-color-stroke-interactive-neutral-disabled); } } /** * Tertiary buttons. */ &.is-tertiary { white-space: nowrap; color: $components-color-accent; background: transparent; &:hover:not(:disabled, [aria-disabled="true"], .is-pressed) { background: color-mix(in srgb, $components-color-accent 4%, transparent); color: $components-color-accent-darker-20; } &:active:not(:disabled, [aria-disabled="true"]) { background: color-mix(in srgb, $components-color-accent 8%, transparent); } // Pull left if the tertiary button stands alone after a description, so as to vertically align with items above. p + & { margin-left: -($grid-unit-15 * 0.5); } } /** * Destructive buttons. */ &.is-destructive { --wp-components-color-accent: #{$alert-red}; --wp-components-color-accent-darker-10: #{color.adjust($alert-red, $lightness: -10%)}; --wp-components-color-accent-darker-20: #{color.adjust($alert-red, $lightness: -20%)}; // Only the default variant is styled differently from the non-destructive counterparts. &:not(.is-primary):not(.is-secondary):not(.is-tertiary):not(.is-link) { color: $alert-red; &:hover:not(:disabled, [aria-disabled="true"]) { color: color.adjust($alert-red, $lightness: -20%); } &:active:not(:disabled, [aria-disabled="true"]) { background: $gray-400; } &:disabled, &[aria-disabled="true"] { color: $gray-600; } } &.is-tertiary, &.is-secondary { &:hover:not(:disabled, [aria-disabled="true"]) { background: rgba($alert-red, 0.04); } &:active:not(:disabled, [aria-disabled="true"]) { background: rgba($alert-red, 0.08); } } } /** * Link buttons. */ &.is-link { margin: 0; padding: 0; border: 0; border-radius: 0; background: none; outline: none; text-align: left; font-weight: var(--wpds-typography-font-weight-default); color: $components-color-accent; text-decoration: underline; text-underline-offset: 0.2em; text-decoration-thickness: from-font; @media not (prefers-reduced-motion) { transition-property: border, background, color; transition-duration: 0.05s; transition-timing-function: ease-in-out; } height: auto; &:focus:not(:active) { border-radius: $radius-small; text-decoration: none; } &:disabled, &[aria-disabled="true"] { color: $gray-600; } } &:not(:disabled, [aria-disabled="true"]):active { color: $components-color-foreground; } &:disabled, &[aria-disabled="true"] { cursor: default; color: $gray-600; } &.is-busy, &.is-secondary.is-busy, &.is-secondary.is-busy:disabled, &.is-secondary.is-busy[aria-disabled="true"] { @media not (prefers-reduced-motion) { animation: components-button__busy-animation 2500ms infinite linear; } background-size: 100px 100%; /* stylelint-disable -- Disable reason: This function call looks nicer when each argument is on its own line. */ background-image: linear-gradient( -45deg, // TODO: Prepare for theming (https://github.com/WordPress/gutenberg/pull/45466/files#r1030872724) color.adjust($white, $lightness: -2%) 33%, color.adjust($white, $lightness: -12%) 33%, color.adjust($white, $lightness: -12%) 70%, color.adjust($white, $lightness: -2%) 70% ); /* stylelint-enable */ } &.is-compact { height: $button-size-compact; &.has-icon:not(.has-text) { padding: 0; min-width: $button-size-compact; } } &.is-small { height: var(--wpds-dimension-size-sm); line-height: 22px; padding: 0 8px; font-size: 11px; &.has-icon:not(.has-text) { padding: 0; min-width: var(--wpds-dimension-size-sm); } } &.has-icon { padding: 6px; // Works for 24px icons. Smaller icons are vertically centered by flex alignments. // Icon buttons are square. min-width: $button-size; justify-content: center; &.is-next-40px-default-size { min-width: $button-size-next-default-40px; } .dashicon { display: inline-flex; justify-content: center; align-items: center; padding: 2px; box-sizing: content-box; } &.has-text { justify-content: start; padding-right: $grid-unit-15; padding-left: $grid-unit-10; gap: $grid-unit-05; &.has-icon-right { padding-right: $grid-unit-10; padding-left: $grid-unit-15; } } // Offset the reserved 1px border so it doesn't widen the square // icon button. &:not(.has-text) { svg, .dashicon { margin-inline: -$border-width; } } } // Toggled style. &.is-pressed { &, &:hover { color: $components-color-foreground-inverted; &:not(:disabled, [aria-disabled="true"]) { background: $components-color-foreground; } } &:disabled, &[aria-disabled="true"] { color: $gray-600; &:not(.is-primary):not(.is-secondary):not(.is-tertiary) { color: $components-color-foreground-inverted; background: $gray-600; } } } svg { fill: currentColor; outline: none; flex-shrink: 0; // Optimize for high contrast modes. // See also https://blogs.windows.com/msedgedev/2020/09/17/styling-for-windows-high-contrast-with-new-standards-for-forced-colors/. @media (forced-colors: active) { fill: CanvasText; } } } @keyframes components-button__busy-animation { 0% { background-position: 200px 0; } }