mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
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:
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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 {
|
||||||
|
Reference in New Issue
Block a user