411 lines
13 KiB
CSS
411 lines
13 KiB
CSS
/*
|
|
* noVNC general input element CSS
|
|
* Copyright (C) 2025 The noVNC authors
|
|
* noVNC is licensed under the MPL 2.0 (see LICENSE.txt)
|
|
* This file is licensed under the 2-Clause BSD license (see LICENSE.txt).
|
|
*/
|
|
|
|
/* ------- SHARED BETWEEN INPUT ELEMENTS -------- */
|
|
|
|
:root {
|
|
--input-xpadding: 1em;
|
|
}
|
|
|
|
input,
|
|
textarea,
|
|
button,
|
|
select,
|
|
input::file-selector-button {
|
|
padding: 0.5em var(--input-xpadding);
|
|
border-radius: 6px;
|
|
appearance: none;
|
|
|
|
/* Respect standard font settings */
|
|
font: inherit;
|
|
}
|
|
input:disabled,
|
|
textarea:disabled,
|
|
button:disabled,
|
|
select:disabled,
|
|
label[disabled] {
|
|
opacity: 0.4;
|
|
}
|
|
|
|
input:focus-visible,
|
|
textarea:focus-visible,
|
|
button:focus-visible,
|
|
select:focus-visible,
|
|
input:focus-visible::file-selector-button {
|
|
outline: 2px solid var(--novnc-lightblue);
|
|
outline-offset: 1px;
|
|
}
|
|
|
|
/* ------- TEXT INPUT -------- */
|
|
|
|
input:not([type]),
|
|
input[type=date],
|
|
input[type=datetime-local],
|
|
input[type=email],
|
|
input[type=month],
|
|
input[type=number],
|
|
input[type=password],
|
|
input[type=search],
|
|
input[type=tel],
|
|
input[type=text],
|
|
input[type=time],
|
|
input[type=url],
|
|
input[type=week],
|
|
textarea {
|
|
border: 1px solid var(--novnc-lightgrey);
|
|
/* Account for borders on text inputs, buttons dont have borders */
|
|
padding: calc(0.5em - 1px) var(--input-xpadding);
|
|
}
|
|
input:not([type]):focus-visible,
|
|
input[type=date]:focus-visible,
|
|
input[type=datetime-local]:focus-visible,
|
|
input[type=email]:focus-visible,
|
|
input[type=month]:focus-visible,
|
|
input[type=number]:focus-visible,
|
|
input[type=password]:focus-visible,
|
|
input[type=search]:focus-visible,
|
|
input[type=tel]:focus-visible,
|
|
input[type=text]:focus-visible,
|
|
input[type=time]:focus-visible,
|
|
input[type=url]:focus-visible,
|
|
input[type=week]:focus-visible,
|
|
textarea:focus-visible {
|
|
outline-offset: -1px;
|
|
}
|
|
|
|
textarea {
|
|
margin: unset; /* Remove Firefox's built in margin */
|
|
/* Prevent layout from shifting when scrollbars show */
|
|
scrollbar-gutter: stable;
|
|
/* Make textareas show at minimum one line. This does not work when
|
|
using box-sizing border-box, in which case, vertical padding and
|
|
border width needs to be taken into account. */
|
|
min-height: 1em;
|
|
vertical-align: baseline; /* Firefox gives "text-bottom" by default */
|
|
}
|
|
|
|
/* ------- BUTTON ACTIVATIONS -------- */
|
|
|
|
/* A color overlay that depends on the activation level. The level can then be
|
|
set for different states on an element, for example hover and click on a
|
|
<button>. */
|
|
input, button, select, option,
|
|
input::file-selector-button,
|
|
.button-activations {
|
|
--button-activation-level: 0;
|
|
/* Note that CSS variables aren't functions, beware when inheriting */
|
|
--button-activation-alpha: calc(0.08 * var(--button-activation-level));
|
|
/* FIXME: We want the image() function instead of the linear-gradient()
|
|
function below. But it's not supported in the browsers yet. */
|
|
--button-activation-overlay:
|
|
linear-gradient(rgba(0, 0, 0, var(--button-activation-alpha))
|
|
100%, transparent);
|
|
--button-activation-overlay-light:
|
|
linear-gradient(rgba(255, 255, 255, calc(0.23 * var(--button-activation-level)))
|
|
100%, transparent);
|
|
}
|
|
.button-activations {
|
|
background-image: var(--button-activation-overlay);
|
|
|
|
/* Disable Chrome's touch tap highlight to avoid conflicts with overlay */
|
|
-webkit-tap-highlight-color: transparent;
|
|
}
|
|
/* When we want the light overlay on activations instead.
|
|
This is best used on elements with darker backgrounds. */
|
|
.button-activations.light-overlay {
|
|
background-image: var(--button-activation-overlay-light);
|
|
/* Can't use the normal blend mode since that gives washed out colors. */
|
|
/* FIXME: For elements with these activation overlays we'd like only
|
|
the luminosity to change. The proprty "background-blend-mode" set
|
|
to "luminosity" sounds good, but it doesn't work as intended,
|
|
see: https://bugzilla.mozilla.org/show_bug.cgi?id=1806417 */
|
|
background-blend-mode: overlay;
|
|
}
|
|
|
|
input:hover, button:hover, select:hover, option:hover,
|
|
input::file-selector-button:hover,
|
|
.button-activations:hover {
|
|
--button-activation-level: 1;
|
|
}
|
|
/* Unfortunately we have to disable the :hover effect on touch devices,
|
|
otherwise the style lingers after tapping the button. */
|
|
@media (any-pointer: coarse) {
|
|
input:hover, button:hover, select:hover, option:hover,
|
|
input::file-selector-button:hover,
|
|
.button-activations:hover {
|
|
--button-activation-level: 0;
|
|
}
|
|
}
|
|
input:active, button:active, select:active, option:active,
|
|
input::file-selector-button:active,
|
|
.button-activations:active {
|
|
--button-activation-level: 2;
|
|
}
|
|
input:disabled, button:disabled, select:disabled, select:disabled option,
|
|
input:disabled::file-selector-button,
|
|
.button-activations:disabled {
|
|
--button-activation-level: 0;
|
|
}
|
|
|
|
/* ------- BUTTONS -------- */
|
|
|
|
input[type=button],
|
|
input[type=color],
|
|
input[type=image],
|
|
input[type=reset],
|
|
input[type=submit],
|
|
input::file-selector-button,
|
|
button,
|
|
select {
|
|
border: none;
|
|
color: black;
|
|
font-weight: bold;
|
|
background-color: var(--novnc-buttongrey);
|
|
background-image: var(--button-activation-overlay);
|
|
|
|
/* Disable Chrome's touch tap highlight */
|
|
-webkit-tap-highlight-color: transparent;
|
|
}
|
|
input[type=image]:disabled {
|
|
/* See Firefox bug:
|
|
https://bugzilla.mozilla.org/show_bug.cgi?id=1798304 */
|
|
cursor: default;
|
|
}
|
|
|
|
/* -- SHARED BETWEEN CHECKBOXES AND RADIOBUTTONS -- */
|
|
|
|
input[type=radio],
|
|
input[type=checkbox] {
|
|
display: inline-flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
background-color: var(--novnc-buttongrey);
|
|
background-image: var(--button-activation-overlay);
|
|
/* Disable Chrome's touch tap highlight to avoid conflicts with overlay */
|
|
-webkit-tap-highlight-color: transparent;
|
|
width: 16px;
|
|
--checkradio-height: 16px;
|
|
height: var(--checkradio-height);
|
|
padding: 0;
|
|
margin: 0 6px 0 0;
|
|
/* Don't have transitions for outline in order to be consistent
|
|
with other elements */
|
|
transition: all 0.2s, outline-color 0s, outline-offset 0s;
|
|
|
|
/* A transparent outline in order to work around a graphical clipping issue
|
|
in WebKit. See bug: https://bugs.webkit.org/show_bug.cgi?id=256003 */
|
|
outline: 1px solid transparent;
|
|
position: relative; /* Since ::before & ::after are absolute positioned */
|
|
|
|
/* We want to align with the middle of capital letters, this requires
|
|
a workaround. The default behavior is to align the bottom of the element
|
|
on top of the text baseline, this is too far up.
|
|
We want to push the element down half the difference in height between
|
|
it and a capital X. In our font, the height of a capital "X" is 0.698em.
|
|
*/
|
|
vertical-align: calc(0px - (var(--checkradio-height) - 0.698em) / 2);
|
|
/* FIXME: Could write 1cap instead of 0.698em, but it's only supported in
|
|
Firefox as of 2023 */
|
|
/* FIXME: We probably want to use round() here, see bug 8148 */
|
|
}
|
|
input[type=radio]:focus-visible,
|
|
input[type=checkbox]:focus-visible {
|
|
outline-color: var(--novnc-lightblue);
|
|
}
|
|
input[type=checkbox]::before,
|
|
input[type=checkbox]::after,
|
|
input[type=radio]::before,
|
|
input[type=radio]::after {
|
|
content: "";
|
|
display: block; /* width & height doesn't work on inline elements */
|
|
transition: inherit;
|
|
/* Let's prevent the pseudo-elements from taking up layout space so that
|
|
the ::before and ::after pseudo-elements can be in the same place. This
|
|
is also required for vertical-align: baseline to work like we want it to
|
|
on radio/checkboxes. If the pseudo-elements take up layout space, the
|
|
baseline of text inside them will be used instead. */
|
|
position: absolute;
|
|
}
|
|
input[type=checkbox]::after,
|
|
input[type=radio]::after {
|
|
width: 10px;
|
|
height: 2px;
|
|
background-color: transparent;
|
|
border-radius: 2px;
|
|
}
|
|
|
|
/* ------- CHECKBOXES ------- */
|
|
|
|
input[type=checkbox] {
|
|
border-radius: 4px;
|
|
}
|
|
input[type=checkbox]:checked,
|
|
input[type=checkbox]:indeterminate {
|
|
background-color: var(--novnc-blue);
|
|
background-image: var(--button-activation-overlay-light);
|
|
background-blend-mode: overlay;
|
|
}
|
|
input[type=checkbox]::before {
|
|
width: 25%;
|
|
height: 55%;
|
|
border-style: solid;
|
|
border-color: transparent;
|
|
border-width: 0 2px 2px 0;
|
|
border-radius: 1px;
|
|
transform: translateY(-1px) rotate(35deg);
|
|
}
|
|
input[type=checkbox]:checked::before {
|
|
border-color: white;
|
|
}
|
|
input[type=checkbox]:indeterminate::after {
|
|
background-color: white;
|
|
}
|
|
|
|
/* ------- RADIO BUTTONS ------- */
|
|
|
|
input[type=radio] {
|
|
border-radius: 50%;
|
|
border: 1px solid transparent; /* To ensure a smooth transition */
|
|
}
|
|
input[type=radio]:checked {
|
|
border: 4px solid var(--novnc-blue);
|
|
background-color: white;
|
|
/* button-activation-overlay should be removed from the radio
|
|
element to not interfere with button-activation-overlay-light
|
|
that is set on the ::before element. */
|
|
background-image: none;
|
|
}
|
|
input[type=radio]::before {
|
|
width: inherit;
|
|
height: inherit;
|
|
border-radius: inherit;
|
|
/* We can achieve the highlight overlay effect on border colors by
|
|
setting button-activation-overlay-light on an element that stays
|
|
on top (z-axis) of the element with a border. */
|
|
background-image: var(--button-activation-overlay-light);
|
|
mix-blend-mode: overlay;
|
|
opacity: 0;
|
|
}
|
|
input[type=radio]:checked::before {
|
|
opacity: 1;
|
|
}
|
|
input[type=radio]:indeterminate::after {
|
|
background-color: black;
|
|
}
|
|
|
|
/* ------- RANGE SLIDERS ------- */
|
|
|
|
input[type=range] {
|
|
border: unset;
|
|
border-radius: 3px;
|
|
height: 20px;
|
|
padding: 0;
|
|
background: transparent;
|
|
}
|
|
/* -webkit-slider.. & -moz-range.. cant be in selector lists:
|
|
https://bugs.chromium.org/p/chromium/issues/detail?id=1154623 */
|
|
input[type=range]::-webkit-slider-runnable-track {
|
|
background-color: var(--novnc-blue);
|
|
height: 6px;
|
|
border-radius: 3px;
|
|
}
|
|
input[type=range]::-moz-range-track {
|
|
background-color: var(--novnc-blue);
|
|
height: 6px;
|
|
border-radius: 3px;
|
|
}
|
|
input[type=range]::-webkit-slider-thumb {
|
|
appearance: none;
|
|
width: 18px;
|
|
height: 20px;
|
|
border-radius: 6px;
|
|
background-color: white;
|
|
background-image: var(--button-activation-overlay);
|
|
/* Disable Chrome's touch tap highlight to avoid conflicts with overlay */
|
|
-webkit-tap-highlight-color: transparent;
|
|
border: 1px solid dimgray;
|
|
margin-top: -7px;
|
|
}
|
|
input[type=range]::-moz-range-thumb {
|
|
appearance: none;
|
|
width: 18px;
|
|
height: 20px;
|
|
border-radius: 6px;
|
|
background-color: white;
|
|
background-image: var(--button-activation-overlay);
|
|
border: 1px solid dimgray;
|
|
margin-top: -7px;
|
|
}
|
|
|
|
/* ------- FILE CHOOSERS ------- */
|
|
|
|
input[type=file] {
|
|
background-image: none;
|
|
border: none;
|
|
}
|
|
input::file-selector-button {
|
|
margin-right: 6px;
|
|
}
|
|
input[type=file]:focus-visible {
|
|
outline: none; /* We outline the button instead of the entire element */
|
|
}
|
|
|
|
/* ------- SELECT BUTTONS ------- */
|
|
|
|
select {
|
|
--select-arrow: url('data:image/svg+xml;utf8, \
|
|
<svg width="11" height="6" version="1.1" viewBox="0 0 11 6" \
|
|
xmlns="http://www.w3.org/2000/svg"> \
|
|
<path d="m10.5.5-5 5-5-5" fill="none" \
|
|
stroke="black" stroke-width="1.5" \
|
|
stroke-linecap="round" stroke-linejoin="round"/> \
|
|
</svg>');
|
|
|
|
/* FIXME: A bug in Firefox, requires a workaround for the background:
|
|
https://bugzilla.mozilla.org/show_bug.cgi?id=1810958 */
|
|
/* The dropdown list will show the select element's background above and
|
|
below the options in Firefox. We want the entire dropdown to be white. */
|
|
background-color: white;
|
|
/* However, we don't want the select element to actually show a white
|
|
background, so let's place a gradient above it with the color we want. */
|
|
--grey-background: linear-gradient(var(--novnc-buttongrey) 100%,
|
|
transparent);
|
|
background-image:
|
|
var(--select-arrow),
|
|
var(--button-activation-overlay),
|
|
var(--grey-background);
|
|
background-position: calc(100% - var(--input-xpadding)), left top, left top;
|
|
background-repeat: no-repeat;
|
|
padding-right: calc(2*var(--input-xpadding) + 11px);
|
|
}
|
|
/* FIXME: :active isn't set when the <select> is opened in Firefox:
|
|
https://bugzilla.mozilla.org/show_bug.cgi?id=1805406 */
|
|
select:active {
|
|
/* Rotated arrow */
|
|
background-image: url('data:image/svg+xml;utf8, \
|
|
<svg width="11" height="6" version="1.1" viewBox="0 0 11 6" \
|
|
xmlns="http://www.w3.org/2000/svg" transform="rotate(180)"> \
|
|
<path d="m10.5.5-5 5-5-5" fill="none" \
|
|
stroke="black" stroke-width="1.5" \
|
|
stroke-linecap="round" stroke-linejoin="round"/> \
|
|
</svg>'),
|
|
var(--button-activation-overlay),
|
|
var(--grey-background);
|
|
}
|
|
select:disabled {
|
|
background-image:
|
|
var(--select-arrow),
|
|
var(--grey-background);
|
|
}
|
|
option {
|
|
/* Prevent Chrome from inheriting background-color from the <select> */
|
|
background-color: white;
|
|
color: black;
|
|
font-weight: normal;
|
|
background-image: var(--button-activation-overlay);
|
|
}
|