Merge 0166e5631e6206101f52c08830ad965a5a731919 into 380a1d738b221fecc964260add053997399be4d4

This commit is contained in:
Shaswat Raj 2025-09-27 16:38:36 +01:00 committed by GitHub
commit 17ec14fbe1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 154 additions and 38 deletions

View File

@ -2151,6 +2151,12 @@ progress {
outline: 0; outline: 0;
box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
} }
@media (prefers-contrast: high) {
.form-control:focus {
outline: 2px solid;
outline-offset: 2px;
}
}
.form-control::-webkit-date-and-time-value { .form-control::-webkit-date-and-time-value {
min-width: 85px; min-width: 85px;
height: 1.5em; height: 1.5em;
@ -3007,6 +3013,12 @@ textarea.form-control-lg {
outline: 0; outline: 0;
box-shadow: var(--bs-btn-focus-box-shadow); box-shadow: var(--bs-btn-focus-box-shadow);
} }
@media (prefers-contrast: high) {
.btn:focus-visible {
outline: 2px solid;
outline-offset: 2px;
}
}
.btn-check:focus-visible + .btn { .btn-check:focus-visible + .btn {
border-color: var(--bs-btn-hover-border-color); border-color: var(--bs-btn-hover-border-color);
outline: 0; outline: 0;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -2149,6 +2149,12 @@ progress {
outline: 0; outline: 0;
box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
} }
@media (prefers-contrast: high) {
.form-control:focus {
outline: 2px solid;
outline-offset: 2px;
}
}
.form-control::-webkit-date-and-time-value { .form-control::-webkit-date-and-time-value {
min-width: 85px; min-width: 85px;
height: 1.5em; height: 1.5em;
@ -3005,6 +3011,12 @@ textarea.form-control-lg {
outline: 0; outline: 0;
box-shadow: var(--bs-btn-focus-box-shadow); box-shadow: var(--bs-btn-focus-box-shadow);
} }
@media (prefers-contrast: high) {
.btn:focus-visible {
outline: 2px solid;
outline-offset: 2px;
}
}
.btn-check:focus-visible + .btn { .btn-check:focus-visible + .btn {
border-color: var(--bs-btn-hover-border-color); border-color: var(--bs-btn-hover-border-color);
outline: 0; outline: 0;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -29,7 +29,7 @@
line-height: var(--#{$prefix}btn-line-height); line-height: var(--#{$prefix}btn-line-height);
color: var(--#{$prefix}btn-color); color: var(--#{$prefix}btn-color);
text-align: center; text-align: center;
text-decoration: if($link-decoration == none, null, none); text-decoration: if($link-decoration ==none, null, none);
white-space: $btn-white-space; white-space: $btn-white-space;
vertical-align: middle; vertical-align: middle;
cursor: if($enable-button-pointers, pointer, null); cursor: if($enable-button-pointers, pointer, null);
@ -42,12 +42,12 @@
&:hover { &:hover {
color: var(--#{$prefix}btn-hover-color); color: var(--#{$prefix}btn-hover-color);
text-decoration: if($link-hover-decoration == underline, none, null); text-decoration: if($link-hover-decoration ==underline, none, null);
background-color: var(--#{$prefix}btn-hover-bg); background-color: var(--#{$prefix}btn-hover-bg);
border-color: var(--#{$prefix}btn-hover-border-color); border-color: var(--#{$prefix}btn-hover-border-color);
} }
.btn-check + &:hover { .btn-check+&:hover {
// override for the checkbox/radio buttons // override for the checkbox/radio buttons
color: var(--#{$prefix}btn-color); color: var(--#{$prefix}btn-color);
background-color: var(--#{$prefix}btn-bg); background-color: var(--#{$prefix}btn-bg);
@ -59,27 +59,41 @@
@include gradient-bg(var(--#{$prefix}btn-hover-bg)); @include gradient-bg(var(--#{$prefix}btn-hover-bg));
border-color: var(--#{$prefix}btn-hover-border-color); border-color: var(--#{$prefix}btn-hover-border-color);
outline: 0; outline: 0;
// Avoid using mixin so we can pass custom focus shadow properly // Avoid using mixin so we can pass custom focus shadow properly
@if $enable-shadows { @if $enable-shadows {
box-shadow: var(--#{$prefix}btn-box-shadow), var(--#{$prefix}btn-focus-box-shadow); box-shadow: var(--#{$prefix}btn-box-shadow),
} @else { var(--#{$prefix}btn-focus-box-shadow);
}
@else {
box-shadow: var(--#{$prefix}btn-focus-box-shadow); box-shadow: var(--#{$prefix}btn-focus-box-shadow);
} }
// High contrast mode fallback - provides visible focus indicator when box-shadow is disabled
@media (prefers-contrast: high) {
outline: 2px solid;
outline-offset: 2px;
}
} }
.btn-check:focus-visible + & { .btn-check:focus-visible+& {
border-color: var(--#{$prefix}btn-hover-border-color); border-color: var(--#{$prefix}btn-hover-border-color);
outline: 0; outline: 0;
// Avoid using mixin so we can pass custom focus shadow properly // Avoid using mixin so we can pass custom focus shadow properly
@if $enable-shadows { @if $enable-shadows {
box-shadow: var(--#{$prefix}btn-box-shadow), var(--#{$prefix}btn-focus-box-shadow); box-shadow: var(--#{$prefix}btn-box-shadow),
} @else { var(--#{$prefix}btn-focus-box-shadow);
}
@else {
box-shadow: var(--#{$prefix}btn-focus-box-shadow); box-shadow: var(--#{$prefix}btn-focus-box-shadow);
} }
} }
.btn-check:checked + &, .btn-check:checked+&,
:not(.btn-check) + &:active, :not(.btn-check)+&:active,
&:first-child:active, &:first-child:active,
&.active, &.active,
&.show { &.show {
@ -91,20 +105,28 @@
@include box-shadow(var(--#{$prefix}btn-active-shadow)); @include box-shadow(var(--#{$prefix}btn-active-shadow));
&:focus-visible { &:focus-visible {
// Avoid using mixin so we can pass custom focus shadow properly // Avoid using mixin so we can pass custom focus shadow properly
@if $enable-shadows { @if $enable-shadows {
box-shadow: var(--#{$prefix}btn-active-shadow), var(--#{$prefix}btn-focus-box-shadow); box-shadow: var(--#{$prefix}btn-active-shadow),
} @else { var(--#{$prefix}btn-focus-box-shadow);
}
@else {
box-shadow: var(--#{$prefix}btn-focus-box-shadow); box-shadow: var(--#{$prefix}btn-focus-box-shadow);
} }
} }
} }
.btn-check:checked:focus-visible + & { .btn-check:checked:focus-visible+& {
// Avoid using mixin so we can pass custom focus shadow properly // Avoid using mixin so we can pass custom focus shadow properly
@if $enable-shadows { @if $enable-shadows {
box-shadow: var(--#{$prefix}btn-active-shadow), var(--#{$prefix}btn-focus-box-shadow); box-shadow: var(--#{$prefix}btn-active-shadow),
} @else { var(--#{$prefix}btn-focus-box-shadow);
}
@else {
box-shadow: var(--#{$prefix}btn-focus-box-shadow); box-shadow: var(--#{$prefix}btn-focus-box-shadow);
} }
} }
@ -130,25 +152,25 @@
// scss-docs-start btn-variant-loops // scss-docs-start btn-variant-loops
@each $color, $value in $theme-colors { @each $color, $value in $theme-colors {
.btn-#{$color} { .btn-#{$color} {
@if $color == "light" { @if $color =="light" {
@include button-variant( @include button-variant($value,
$value,
$value, $value,
$hover-background: shade-color($value, $btn-hover-bg-shade-amount), $hover-background: shade-color($value, $btn-hover-bg-shade-amount),
$hover-border: shade-color($value, $btn-hover-border-shade-amount), $hover-border: shade-color($value, $btn-hover-border-shade-amount),
$active-background: shade-color($value, $btn-active-bg-shade-amount), $active-background: shade-color($value, $btn-active-bg-shade-amount),
$active-border: shade-color($value, $btn-active-border-shade-amount) $active-border: shade-color($value, $btn-active-border-shade-amount));
); }
} @else if $color == "dark" {
@include button-variant( @else if $color =="dark" {
$value, @include button-variant($value,
$value, $value,
$hover-background: tint-color($value, $btn-hover-bg-tint-amount), $hover-background: tint-color($value, $btn-hover-bg-tint-amount),
$hover-border: tint-color($value, $btn-hover-border-tint-amount), $hover-border: tint-color($value, $btn-hover-border-tint-amount),
$active-background: tint-color($value, $btn-active-bg-tint-amount), $active-background: tint-color($value, $btn-active-bg-tint-amount),
$active-border: tint-color($value, $btn-active-border-tint-amount) $active-border: tint-color($value, $btn-active-border-tint-amount));
); }
} @else {
@else {
@include button-variant($value, $value); @include button-variant($value, $value);
} }
} }
@ -159,6 +181,7 @@
@include button-outline-variant($value); @include button-outline-variant($value);
} }
} }
// scss-docs-end btn-variant-loops // scss-docs-end btn-variant-loops
@ -182,6 +205,7 @@
--#{$prefix}btn-focus-shadow-rgb: #{$btn-link-focus-shadow-rgb}; --#{$prefix}btn-focus-shadow-rgb: #{$btn-link-focus-shadow-rgb};
text-decoration: $link-decoration; text-decoration: $link-decoration;
@if $enable-gradients { @if $enable-gradients {
background-image: none; background-image: none;
} }
@ -213,4 +237,4 @@
.btn-sm { .btn-sm {
@include button-size($btn-padding-y-sm, $btn-padding-x-sm, $btn-font-size-sm, $btn-border-radius-sm); @include button-size($btn-padding-y-sm, $btn-padding-x-sm, $btn-font-size-sm, $btn-border-radius-sm);
} }

View File

@ -36,12 +36,21 @@
background-color: $input-focus-bg; background-color: $input-focus-bg;
border-color: $input-focus-border-color; border-color: $input-focus-border-color;
outline: 0; outline: 0;
@if $enable-shadows { @if $enable-shadows {
@include box-shadow($input-box-shadow, $input-focus-box-shadow); @include box-shadow($input-box-shadow, $input-focus-box-shadow);
} @else { }
@else {
// Avoid using mixin so we can pass custom focus shadow properly // Avoid using mixin so we can pass custom focus shadow properly
box-shadow: $input-focus-box-shadow; box-shadow: $input-focus-box-shadow;
} }
// High contrast mode fallback - provides visible focus indicator when box-shadow is disabled
@media (prefers-contrast: high) {
outline: 2px solid;
outline-offset: 2px;
}
} }
&::-webkit-date-and-time-value { &::-webkit-date-and-time-value {
@ -56,7 +65,7 @@
// https://github.com/twbs/bootstrap/issues/23307 // https://github.com/twbs/bootstrap/issues/23307
// TODO: we can remove this workaround once https://bugs.webkit.org/show_bug.cgi?id=198959 is resolved // TODO: we can remove this workaround once https://bugs.webkit.org/show_bug.cgi?id=198959 is resolved
// Multiply line-height by 1em if it has no unit // Multiply line-height by 1em if it has no unit
height: if(unit($input-line-height) == "", $input-line-height * 1em, $input-line-height); height: if(unit($input-line-height)=="", $input-line-height * 1em, $input-line-height);
// Android Chrome type="date" is taller than the other inputs // Android Chrome type="date" is taller than the other inputs
// because of "margin: 1px 24px 1px 4px" inside the shadow DOM // because of "margin: 1px 24px 1px 4px" inside the shadow DOM
@ -188,6 +197,7 @@ textarea {
min-height: $input-height-lg; min-height: $input-height-lg;
} }
} }
// stylelint-enable selector-no-qualifying-type // stylelint-enable selector-no-qualifying-type
.form-control-color { .form-control-color {
@ -209,6 +219,11 @@ textarea {
@include border-radius($input-border-radius); @include border-radius($input-border-radius);
} }
&.form-control-sm { height: $input-height-sm; } &.form-control-sm {
&.form-control-lg { height: $input-height-lg; } height: $input-height-sm;
} }
&.form-control-lg {
height: $input-height-lg;
}
}

View File

@ -0,0 +1,53 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>High Contrast Focus Test</title>
<link href="dist/css/bootstrap.css" rel="stylesheet">
<style>
/* Simulate high contrast mode for testing */
@media (prefers-contrast: high) {
body {
background: black;
color: white;
}
}
</style>
</head>
<body>
<div class="container mt-5">
<h1>High Contrast Focus Indicator Test</h1>
<p>This page demonstrates the improved focus indicators for high contrast mode.</p>
<div class="mb-3">
<label for="testInput" class="form-label">Test Input</label>
<input type="text" class="form-control" id="testInput" placeholder="Focus on this input">
</div>
<div class="mb-3">
<label for="testTextarea" class="form-label">Test Textarea</label>
<textarea class="form-control" id="testTextarea" rows="3" placeholder="Focus on this textarea"></textarea>
</div>
<div class="mb-3">
<button type="button" class="btn btn-primary">Primary Button</button>
<button type="button" class="btn btn-secondary">Secondary Button</button>
</div>
<div class="alert alert-info">
<strong>Testing Instructions:</strong>
<ul>
<li>Tab through the form elements to see focus indicators</li>
<li>In normal mode, you'll see the blue box-shadow focus ring</li>
<li>In high contrast mode (or when box-shadow is disabled), you'll see a solid outline</li>
<li>To test high contrast mode: Enable it in your OS settings or use browser dev tools to simulate it
</li>
</ul>
</div>
</div>
</body>
</html>