Skip to content

Commit 2846e8a

Browse files
committed
Improve styling for PlayButton and PlusButton components
1 parent 430208d commit 2846e8a

4 files changed

Lines changed: 167 additions & 3 deletions

File tree

HomeSpeaker.WebAssembly/Components/Music/Player/PlayButtonWithDropdown.razor

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
@inject IJSRuntime JsRuntime
77

88
<div class="position-relative d-inline-block" @ref="containerRef">
9-
<button @onclick="ToggleMenu" class="btn btn-outline-primary" title="Play">
9+
<button @onclick="ToggleMenu" class="btn btn-adaptive-contrast" title="Play">
1010
<span class="oi oi-media-play" />
11-
</button> @if (showMenu)
11+
</button>@if (showMenu)
1212
{
1313
<div class="dropdown-menu show position-absolute" style="top: 100%; @dropdownPositionStyle z-index: 10000; min-width: 220px;">
1414
<button class="dropdown-item" @onclick="PlayOnServer">

HomeSpeaker.WebAssembly/Components/UI/PlusButtonWithMenu.razor

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
@inject IJSRuntime JsRuntime
33

44
<div class="position-relative d-inline-block" @ref="containerRef">
5-
<button @onclick="ToggleMenu" class="btn btn-outline-secondary" title="Add to queue or playlist">
5+
<button @onclick="ToggleMenu" class="btn btn-adaptive-contrast" title="Add to queue or playlist">
66
<span class="oi oi-plus" />
77
</button>
88

HomeSpeaker.WebAssembly/wwwroot/css/app.css

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,122 @@ a, .btn-link {
3838
color: red;
3939
}
4040

41+
/* Adaptive contrast buttons - automatically adjust based on background */
42+
.btn-adaptive-contrast {
43+
/* Default appearance for light backgrounds - dark buttons */
44+
border: 1px solid rgba(73, 80, 87, 0.6);
45+
color: rgba(73, 80, 87, 0.9);
46+
background-color: transparent;
47+
transition: all 0.2s ease;
48+
position: relative;
49+
padding: 0.375rem 0.75rem;
50+
border-radius: 0.375rem;
51+
/* Add a subtle drop shadow for better visibility */
52+
filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.1));
53+
}
54+
55+
/* Hover state for light backgrounds - show solid border and slight background */
56+
.btn-adaptive-contrast:hover {
57+
border-color: rgba(73, 80, 87, 1) !important;
58+
color: rgba(73, 80, 87, 1);
59+
background-color: rgba(73, 80, 87, 0.1);
60+
transform: scale(1.05);
61+
filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.15));
62+
}
63+
64+
/* Focus state */
65+
.btn-adaptive-contrast:focus {
66+
outline: none;
67+
box-shadow: 0 0 0 0.25rem rgba(73, 80, 87, 0.25);
68+
border-color: rgba(73, 80, 87, 1) !important;
69+
}
70+
71+
/* Active state */
72+
.btn-adaptive-contrast:active {
73+
transform: scale(0.95);
74+
background-color: rgba(73, 80, 87, 0.2);
75+
}
76+
77+
/* Dark backgrounds - light buttons with better contrast */
78+
.bg-primary .btn-adaptive-contrast,
79+
.bg-secondary .btn-adaptive-contrast,
80+
.bg-dark .btn-adaptive-contrast,
81+
.bg-info .btn-adaptive-contrast,
82+
[class*="bg-primary"] .btn-adaptive-contrast,
83+
[class*="bg-secondary"] .btn-adaptive-contrast,
84+
[class*="bg-dark"] .btn-adaptive-contrast,
85+
[style*="background-color: rgb(49, 90, 131)"] .btn-adaptive-contrast,
86+
[style*="background-color: #315a83"] .btn-adaptive-contrast,
87+
[style*="background-color: rgb(13, 110, 253)"] .btn-adaptive-contrast,
88+
[style*="background-color: rgb(51, 102, 204)"] .btn-adaptive-contrast,
89+
[style*="background-color: rgb(108, 117, 125)"] .btn-adaptive-contrast {
90+
border-color: rgba(248, 249, 250, 0.6) !important;
91+
color: rgba(248, 249, 250, 0.9) !important;
92+
filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.3));
93+
text-shadow: 0 0 1px rgba(0, 0, 0, 0.5);
94+
}
95+
96+
/* Hover state for dark backgrounds - bright white border and background */
97+
.bg-primary .btn-adaptive-contrast:hover,
98+
.bg-secondary .btn-adaptive-contrast:hover,
99+
.bg-dark .btn-adaptive-contrast:hover,
100+
.bg-info .btn-adaptive-contrast:hover,
101+
[class*="bg-primary"] .btn-adaptive-contrast:hover,
102+
[class*="bg-secondary"] .btn-adaptive-contrast:hover,
103+
[class*="bg-dark"] .btn-adaptive-contrast:hover,
104+
[style*="background-color: rgb(49, 90, 131)"] .btn-adaptive-contrast:hover,
105+
[style*="background-color: #315a83"] .btn-adaptive-contrast:hover,
106+
[style*="background-color: rgb(13, 110, 253)"] .btn-adaptive-contrast:hover,
107+
[style*="background-color: rgb(51, 102, 204)"] .btn-adaptive-contrast:hover,
108+
[style*="background-color: rgb(108, 117, 125)"] .btn-adaptive-contrast:hover {
109+
border-color: rgba(248, 249, 250, 1) !important;
110+
color: rgba(248, 249, 250, 1) !important;
111+
background-color: rgba(248, 249, 250, 0.15) !important;
112+
filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.4));
113+
text-shadow: 0 0 2px rgba(0, 0, 0, 0.7);
114+
transform: scale(1.05);
115+
}
116+
117+
/* Focus state for dark backgrounds */
118+
.bg-primary .btn-adaptive-contrast:focus,
119+
.bg-secondary .btn-adaptive-contrast:focus,
120+
.bg-dark .btn-adaptive-contrast:focus,
121+
[class*="bg-primary"] .btn-adaptive-contrast:focus,
122+
[class*="bg-secondary"] .btn-adaptive-contrast:focus,
123+
[class*="bg-dark"] .btn-adaptive-contrast:focus,
124+
[style*="background-color: rgb(49, 90, 131)"] .btn-adaptive-contrast:focus,
125+
[style*="background-color: #315a83"] .btn-adaptive-contrast:focus {
126+
box-shadow: 0 0 0 0.25rem rgba(248, 249, 250, 0.25) !important;
127+
border-color: rgba(248, 249, 250, 1) !important;
128+
}
129+
130+
/* Ensure icons inherit the color properly */
131+
.btn-adaptive-contrast .oi,
132+
.btn-adaptive-contrast .fas,
133+
.btn-adaptive-contrast .fa,
134+
.btn-adaptive-contrast .bi {
135+
color: inherit;
136+
transition: inherit;
137+
}
138+
139+
/* Force high contrast mode for accessibility */
140+
@media (prefers-contrast: high) {
141+
.btn-adaptive-contrast {
142+
border-width: 2px;
143+
font-weight: 600;
144+
}
145+
146+
.bg-primary .btn-adaptive-contrast,
147+
.bg-secondary .btn-adaptive-contrast,
148+
[class*="bg-primary"] .btn-adaptive-contrast,
149+
[class*="bg-secondary"] .btn-adaptive-contrast {
150+
border-color: white !important;
151+
color: white !important;
152+
text-shadow: 0 0 3px black !important;
153+
}
154+
}
155+
156+
41157
#blazor-error-ui {
42158
background: lightyellow;
43159
bottom: 0;

HomeSpeaker.WebAssembly/wwwroot/index.html

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,54 @@
4141
new bootstrap.Tab(tabElement);
4242
});
4343
};
44+
45+
window.getBackgroundLuminance = function(element) {
46+
try {
47+
// Get the computed background color of the element or its closest parent with a background
48+
let currentElement = element;
49+
let backgroundColor = 'rgba(0, 0, 0, 0)';
50+
51+
while (currentElement && currentElement !== document.body) {
52+
const computedStyle = window.getComputedStyle(currentElement);
53+
backgroundColor = computedStyle.backgroundColor;
54+
55+
// If we found a non-transparent background, use it
56+
if (backgroundColor !== 'rgba(0, 0, 0, 0)' && backgroundColor !== 'transparent') {
57+
break;
58+
}
59+
currentElement = currentElement.parentElement;
60+
}
61+
62+
// If no background found, default to white
63+
if (backgroundColor === 'rgba(0, 0, 0, 0)' || backgroundColor === 'transparent') {
64+
backgroundColor = 'rgb(255, 255, 255)';
65+
}
66+
67+
// Parse RGB values
68+
const rgb = backgroundColor.match(/\d+/g);
69+
if (!rgb || rgb.length < 3) {
70+
return 0.5; // Default middle luminance
71+
}
72+
73+
const r = parseInt(rgb[0]);
74+
const g = parseInt(rgb[1]);
75+
const b = parseInt(rgb[2]);
76+
77+
// Calculate relative luminance using sRGB color space
78+
// Formula from WCAG 2.1 specification
79+
const normalize = (color) => {
80+
const c = color / 255;
81+
return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
82+
};
83+
84+
const luminance = 0.2126 * normalize(r) + 0.7152 * normalize(g) + 0.0722 * normalize(b);
85+
86+
return luminance;
87+
} catch (error) {
88+
console.warn('Error calculating background luminance:', error);
89+
return 0.5; // Default middle luminance
90+
}
91+
};
4492
</script>
4593
</body>
4694

0 commit comments

Comments
 (0)