Switch focus styles to :focus-visible

- Switched dynamic styles to :focus-visible to let the browser decide when to display
- Changed most existing :focus CSS selectors to also use :focus-visible
-Made style variables for focus outlines (main and a faint one)
- Remove focus outline from chat bar buttons
- Fix focus of chat bar highlight, moved to outer border
- Fix buttons in chat backgrounds with keyboard navigation
This commit is contained in:
Wolfsblvt
2024-06-18 00:14:15 +02:00
parent 08a0b1e828
commit dadef92fdf
5 changed files with 52 additions and 54 deletions

View File

@ -98,7 +98,7 @@
font-weight: bold; font-weight: bold;
} }
.logprobs_top_candidate:not([disabled]):hover, .logprobs_top_candidate:not([disabled]):focus { .logprobs_top_candidate:not([disabled]):hover {
background-color: rgba(0, 0, 0, 0.3); background-color: rgba(0, 0, 0, 0.3);
} }

View File

@ -100,10 +100,6 @@ dialog {
gap: 20px; gap: 20px;
} }
.popup-controls .menu_button:focus-within {
outline: 1px solid var(--white100);
}
.menu_button.menu_button_default { .menu_button.menu_button_default {
box-shadow: 0 0 5px var(--white20a); box-shadow: 0 0 5px var(--white20a);
} }
@ -129,7 +125,7 @@ dialog {
-webkit-font-smoothing: subpixel-antialiased; -webkit-font-smoothing: subpixel-antialiased;
} }
.popup-controls .menu_button:hover:focus-within { .popup-controls .menu_button:hover:focus-visible {
filter: brightness(1.3) saturate(1.3); filter: brightness(1.3) saturate(1.3);
} }

View File

@ -119,13 +119,11 @@
opacity: 0.6; opacity: 0.6;
} }
#tagList .tag:has(.tag_remove:hover), #tagList .tag:has(.tag_remove:hover) {
#tagList .tag:has(.tag_remove:focus) {
opacity: 1; opacity: 1;
} }
#tagList .tag:has(.tag_remove:hover) .tag_name, #tagList .tag:has(.tag_remove:hover) .tag_name {
#tagList .tag:has(.tag_remove:focus) .tag_name {
opacity: 0.6; opacity: 0.6;
} }
@ -172,8 +170,7 @@
transition: opacity 200ms; transition: opacity 200ms;
} }
.rm_tag_filter .tag:hover, .rm_tag_filter .tag:hover {
.rm_tag_filter .tag:focus {
opacity: 1; opacity: 1;
filter: brightness(1); filter: brightness(1);
} }
@ -218,7 +215,6 @@
} }
.tag_as_folder:hover, .tag_as_folder:hover,
.tag_as_folder:focus,
.tag_as_folder.flash { .tag_as_folder.flash {
filter: brightness(150%) saturate(0.6) !important; filter: brightness(150%) saturate(0.6) !important;
} }

View File

@ -63,7 +63,7 @@ function applyDynamicFocusStyles(styleSheet, { fromExtension = false } = {}) {
const baseSelector = selector.replace(':hover', PLACEHOLDER).trim(); const baseSelector = selector.replace(':hover', PLACEHOLDER).trim();
hoverRules.push({ baseSelector, rule }); hoverRules.push({ baseSelector, rule });
} else if (isFocus) { } else if (isFocus) {
// We need to make sure that we both remember existing :focus and :focus-within rules // We need to make sure that we remember all existing :focus, :focus-within and :focus-visible rules
const baseSelector = selector.replace(':focus-within', PLACEHOLDER).replace(':focus-visible', PLACEHOLDER).replace(':focus', PLACEHOLDER).trim(); const baseSelector = selector.replace(':focus-within', PLACEHOLDER).replace(':focus-visible', PLACEHOLDER).replace(':focus', PLACEHOLDER).trim();
focusRules.add(baseSelector); focusRules.add(baseSelector);
} }
@ -96,10 +96,13 @@ function applyDynamicFocusStyles(styleSheet, { fromExtension = false } = {}) {
// Only initialize the dynamic stylesheet if needed // Only initialize the dynamic stylesheet if needed
targetStyleSheet ??= getDynamicStyleSheet({ fromExtension }); targetStyleSheet ??= getDynamicStyleSheet({ fromExtension });
// The closest keyboard-equivalent to :hover styling is utilizing the :focus-within for keyboards // The closest keyboard-equivalent to :hover styling is utilizing the :focus-visible rule from modern browsers.
// It let's the browser decide whether a focus highlighting is expected and makes sense.
// So we take all :hover rules that don't have a manually defined focus rule yet, and create their // So we take all :hover rules that don't have a manually defined focus rule yet, and create their
// :focus-within counterpart, which will make the styling work the same for keyboard and mouse // :focus-visible counterpart, which will make the styling work the same for keyboard and mouse.
const focusSelector = rule.selectorText.replace(/:hover/g, ':focus-within'); // If something like :focus-within or a more specific selector like `.blah:has(:focus-visible)` for elements inside,
// it should be manually defined in CSS.
const focusSelector = rule.selectorText.replace(/:hover/g, ':focus-visible');
const focusRule = `${focusSelector} { ${rule.style.cssText} }`; const focusRule = `${focusSelector} { ${rule.style.cssText} }`;
try { try {

View File

@ -51,6 +51,9 @@
--active: rgb(88, 182, 0); --active: rgb(88, 182, 0);
--preferred: rgb(244, 67, 54); --preferred: rgb(244, 67, 54);
--interactable-outline-color: var(--white100);
--interactable-outline-color-faint: var(--white50a);
/*Default Theme, will be changed by ToolCool Color Picker*/ /*Default Theme, will be changed by ToolCool Color Picker*/
--SmartThemeBodyColor: rgb(220, 220, 210); --SmartThemeBodyColor: rgb(220, 220, 210);
@ -223,18 +226,18 @@ table.responsiveTable {
/* Outline for "normal" buttons should only be when actual keyboard navigation is used */ /* Outline for "normal" buttons should only be when actual keyboard navigation is used */
.interactable:focus-visible { .interactable:focus-visible {
outline: 1px solid var(--white100); outline: 1px solid var(--interactable-outline-color);
} }
/* The specific input controls can always have a faint outline, even on mouse interaction, to give a better hint */ /* The specific input controls can always have a faint outline, even on mouse interaction, to give a better hint */
select:focus, select:focus-visible,
input:focus, input:focus-visible,
textarea:focus { textarea:focus-visible {
outline: 1px solid var(--white30a); outline: 1px solid var(--interactable-outline-color-faint);
} }
input[type='checkbox']:focus { input[type='checkbox']:focus-visible {
outline: 1px solid var(--white100); outline: 1px solid var(--interactable-outline-color);
} }
/* General dragover styling */ /* General dragover styling */
@ -699,7 +702,6 @@ body .panelControlBar {
width: var(--bottomFormBlockSize); width: var(--bottomFormBlockSize);
height: var(--bottomFormBlockSize); height: var(--bottomFormBlockSize);
margin: 0; margin: 0;
outline: none;
border: none; border: none;
cursor: pointer; cursor: pointer;
opacity: 0.7; opacity: 0.7;
@ -710,18 +712,11 @@ body .panelControlBar {
} }
#rightSendForm>div:hover, #rightSendForm>div:hover,
#rightSendForm>div:focus, #leftSendForm>div:hover {
#leftSendForm>div:hover,
#leftSendForm>div:focus {
opacity: 1; opacity: 1;
filter: brightness(1.2); filter: brightness(1.2);
} }
#rightSendForm>div:focus,
#leftSendForm>div:focus {
outline: 1px solid var(--white100);
}
#send_but { #send_but {
order: 2; order: 2;
} }
@ -823,7 +818,6 @@ body .panelControlBar {
height: var(--bottomFormBlockSize); height: var(--bottomFormBlockSize);
font-size: var(--bottomFormIconSize); font-size: var(--bottomFormIconSize);
margin: 0; margin: 0;
outline: none;
border: none; border: none;
position: relative; position: relative;
opacity: 0.7; opacity: 0.7;
@ -1223,6 +1217,16 @@ select {
transition: clip-path 200ms; transition: clip-path 200ms;
} }
#send_textarea:focus-visible {
/* Disable outline for the chat bar itself, we add it to the outer div */
outline: none;
}
#send_form:has(#send_textarea:focus-visible) {
border-color: var(--interactable-outline-color-faint);
outline: 1px solid var(--interactable-outline-color-faint);
}
#form_sheld.isExecutingCommandsFromChatInput.script_paused #send_textarea { #form_sheld.isExecutingCommandsFromChatInput.script_paused #send_textarea {
animation-name: script_progress_pulse; animation-name: script_progress_pulse;
animation-duration: 1500ms; animation-duration: 1500ms;
@ -2217,8 +2221,7 @@ input[type="file"] {
transition: all 0.5s ease-in-out; transition: all 0.5s ease-in-out;
} }
.right_menu_button:hover, .right_menu_button:hover {
.right_menu_button:focus {
filter: brightness(150%); filter: brightness(150%);
} }
@ -2239,11 +2242,11 @@ input[type="file"] {
} }
#rm_button_panel_pin_div:hover, #rm_button_panel_pin_div:hover,
#rm_button_panel_pin_div:focus-within, #rm_button_panel_pin_div:has(:focus-visible),
#lm_button_panel_pin_div:hover, #lm_button_panel_pin_div:hover,
#lm_button_panel_pin_div:focus-within, #lm_button_panel_pin_div:has(:focus-visible),
#WI_button_panel_pin_div:hover, #WI_button_panel_pin_div:hover,
#WI_button_panel_pin_div:focus-within { #WI_button_panel_pin_div:has(:focus-visible) {
opacity: 1; opacity: 1;
} }
@ -2731,11 +2734,8 @@ input[type=search]:focus::-webkit-search-cancel-button {
} }
.bogus_folder_select:hover, .bogus_folder_select:hover,
.bogus_folder_select:focus-within,
.character_select:hover, .character_select:hover,
.character_select:focus-within, .avatar-container:hover {
.avatar-container:hover,
.avatar-container:focus-within {
background-color: var(--white30a); background-color: var(--white30a);
} }
@ -2776,19 +2776,23 @@ input[type=search]:focus::-webkit-search-cancel-button {
outline: 2px solid var(--golden); outline: 2px solid var(--golden);
} }
.bg_example:hover.locked .bg_example_lock { .bg_example:hover.locked .bg_example_lock,
.bg_example:focus-within.locked .bg_example_lock {
display: none; display: none;
} }
.bg_example:hover:not(.locked) .bg_example_unlock { .bg_example:hover:not(.locked) .bg_example_unlock,
.bg_example:focus-within:not(.locked) .bg_example_unlock {
display: none; display: none;
} }
.bg_example:hover[custom="true"] .bg_example_edit { .bg_example:hover[custom="true"] .bg_example_edit,
.bg_example:focus-within[custom="true"] .bg_example_edit {
display: none; display: none;
} }
.bg_example:hover[custom="false"] .bg_example_copy { .bg_example:hover[custom="false"] .bg_example_copy,
.bg_example:focus-within[custom="false"] .bg_example_copy {
display: none; display: none;
} }
@ -2828,7 +2832,8 @@ input[type=search]:focus::-webkit-search-cancel-button {
display: none; display: none;
} }
.bg_example:hover .bg_button { .bg_example:hover .bg_button,
.bg_example:focus-within .bg_button {
display: block; display: block;
} }
@ -3570,15 +3575,13 @@ input[type='checkbox'].del_checkbox {
} }
.neo-range-slider:hover, .neo-range-slider:hover,
.neo-range-slider:focus, input[type="range"]:hover {
input[type="range"]:hover,
input[type="range"]:focus {
filter: brightness(1.25); filter: brightness(1.25);
} }
.neo-range-slider:focus, .neo-range-slider:focus-visible,
input[type="range"]:focus { input[type="range"]:focus-visible {
outline: 1px solid var(--white100); outline: 1px solid var(--interactable-outline-color);
} }
.range-block-range { .range-block-range {