315 lines
12 KiB
SCSS
315 lines
12 KiB
SCSS
///
|
|
/// This file regroups the CSS rules made to fix/extend bootstrap in frontend
|
|
/// ==============================================================================
|
|
|
|
// Extend bootstrap to create background and text utilities for gray colors too
|
|
// Note: the card-body rule below needs those grays utilities to be defined
|
|
// before so that the related o-bg-color text-muted rules work.
|
|
@each $color, $value in $grays {
|
|
@include bg-variant(".bg-#{$color}", $value);
|
|
@include text-emphasis-variant(".text-#{$color}", $value);
|
|
}
|
|
|
|
// Restore text-X from BS4 that use text-emphasis-variant
|
|
@each $color, $value in $theme-colors {
|
|
@include text-emphasis-variant(".text-#{$color}", $value);
|
|
}
|
|
|
|
// TODO: To be removed in master (18.1)
|
|
// Define `text-primary-emphasis` class here in order to take priority when in
|
|
// conjunction with other text-[x] classes
|
|
@include text-emphasis-variant(".text-primary-emphasis", $primary-text-emphasis);
|
|
|
|
// Cards
|
|
|
|
.card {
|
|
// Bootstrap sets up background-color using `var(--card-bg)` but forces a
|
|
// color using `var(--body-color)`. It relies on `var(--card-color)` being
|
|
// used on the card-body... but there does not seem to be a valid reason
|
|
// to force the body one on the card above. Given the fact that `card-color`
|
|
// is actually null by default, we end up with an inconsistent body-color
|
|
// forced on the card whatever the value of `card-bg`. In the website case,
|
|
// we often set up `card-bg` to inherit by default, which means the text
|
|
// color would only work if the card was over the body background color.
|
|
// By forcing `card-color` we enforce something consistent and controllable,
|
|
// which by default will result as the card text color just following the
|
|
// parent environment one (as `card-color` is null by default). We assume
|
|
// that if `card-bg` is set, then `card-color` should be too.
|
|
|
|
// Note: doing `color: var(--card-color)` would prevent overriding
|
|
// --body-color in the card context (which is a bit weird) but it does not
|
|
// work: it would override the color given by bg-xxx in the .card.bg-xxx
|
|
// case, which is not what we want.
|
|
--body-color: var(--card-color);
|
|
}
|
|
:where(.card:not([data-vxml])) .card-body {
|
|
// BS4 colored cards do not have a very popular design. This will reset them
|
|
// to a BS3-like one: only the header and footer are colored and the body
|
|
// will use the color of a default card background with a light opacity.
|
|
// Limitation: bg-* utilities cannot be used on card-body elements anymore.
|
|
// Note: these rules need grays utilities to be defined before so that the
|
|
// related o-bg-color text-muted rules work. Since backend and fronted
|
|
// generate these classes differently, this pseudo-class is called in the
|
|
// respective 'bootstrap_review_x' file immediately after gray classes
|
|
// generation.
|
|
@include o-bg-color(rgba($card-bg, $o-card-body-bg-opacity), $important: false);
|
|
|
|
&:first-child {
|
|
@include border-top-radius($card-inner-border-radius);
|
|
}
|
|
&:last-child {
|
|
@include border-bottom-radius($card-inner-border-radius);
|
|
}
|
|
}
|
|
|
|
// Generating bootstrap color buttons was disabled (see import_bootstrap.scss).
|
|
// We do it ourself here with a tweak: we introduce btn-fill-* (working as the
|
|
// normal btn-* classes (in opposition to btn-outline-* classes). We then map
|
|
// the btn-* classes to either btn-fill-* or btn-outline-* classes depending on
|
|
// the configuration. We also allow to define a border-color different than the
|
|
// background color.
|
|
$o-btn-bg-colors: () !default;
|
|
$o-btn-border-colors: () !default;
|
|
@each $color, $value in $theme-colors {
|
|
$-bg-color: map-get($o-btn-bg-colors, $color) or $value;
|
|
$-border-color: map-get($o-btn-border-colors, $color) or $-bg-color;
|
|
.btn-fill-#{$color} {
|
|
@include button-variant($-bg-color, $-border-color);
|
|
}
|
|
}
|
|
@each $color, $value in $theme-colors {
|
|
$-bg-color: map-get($o-btn-bg-colors, $color) or $value;
|
|
$-border-color: map-get($o-btn-border-colors, $color) or $-bg-color;
|
|
.btn-outline-#{$color} {
|
|
@include button-outline-variant($-border-color);
|
|
}
|
|
}
|
|
$o-btn-flat-defaults: () !default;
|
|
$o-btn-outline-defaults: () !default;
|
|
$o-btn-outline-border-width-defaults: () !default;
|
|
@each $color, $value in $theme-colors {
|
|
.btn-#{$color} {
|
|
@if index($o-btn-outline-defaults, $color) {
|
|
@extend .btn-outline-#{$color};
|
|
border-width: map-get($o-btn-outline-border-width-defaults, $color);
|
|
} @else {
|
|
@extend .btn-fill-#{$color};
|
|
@if index($o-btn-flat-defaults, $color) {
|
|
// TODO In master: move definition to web_editor
|
|
@extend .btn.flat !optional;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Highlight '.btn-group's active buttons
|
|
.btn-group .btn-light.active {
|
|
box-shadow: inset 0 0 0 $border-width $component-active-bg;
|
|
border-color: transparent;
|
|
background-color: mix($component-active-bg, $light, 10%);
|
|
}
|
|
|
|
// Compensate navbar brand padding if no visible border
|
|
@if alpha($navbar-dark-toggler-border-color) < 0.001 {
|
|
.navbar-dark .navbar-toggler {
|
|
padding-left: 0;
|
|
padding-right: 0;
|
|
}
|
|
}
|
|
@if alpha($navbar-light-toggler-border-color) < 0.001 {
|
|
.navbar-light .navbar-toggler {
|
|
padding-left: 0;
|
|
padding-right: 0;
|
|
}
|
|
}
|
|
|
|
// Review bootstrap navbar to work with different nav styles
|
|
$o-navbar-nav-pills-link-padding-x: $nav-link-padding-x !default;
|
|
$o-navbar-nav-pills-link-border-radius: $nav-pills-border-radius !default;
|
|
.navbar-nav.nav-pills .nav-link {
|
|
// The rules is needed so that the padding is not reset to 0 in mobile.
|
|
// Also use default nav-link paddings instead of navbar ones.
|
|
padding-right: $o-navbar-nav-pills-link-padding-x;
|
|
padding-left: $o-navbar-nav-pills-link-padding-x;
|
|
|
|
@if $o-navbar-nav-pills-link-border-radius != $nav-pills-border-radius {
|
|
@include border-radius($o-navbar-nav-pills-link-border-radius);
|
|
}
|
|
}
|
|
|
|
.carousel-control-next .visually-hidden {
|
|
left: 50%; // Avoid horizontal scrollbar in Chrome
|
|
}
|
|
|
|
.pagination {
|
|
// Ensure circle for one digit numbers
|
|
font-variant-numeric: tabular-nums;
|
|
}
|
|
|
|
// Modal
|
|
.modal-content {
|
|
// If the text color of the body (used for the text color in modals) is not
|
|
// visible due to insufficient contrast with the modal background, we adjust
|
|
// the text color in the modal using the following code. For example, if the
|
|
// user sets a black background for its website and the text color of the
|
|
// body is white, the text will not be visible on modals with a white
|
|
// background.
|
|
|
|
@if $modal-content-color == null {
|
|
color: adjust-color-to-background($body-color, $modal-content-bg);
|
|
|
|
// This prevents these elements from taking their colors from the body
|
|
// inside a modal.
|
|
// We need to exclude 'oe_structure' that are areas containing editable
|
|
// snippets. Indeed, this code was added in a stable version, and we are
|
|
// doing everything not to alter the content edited by users. For
|
|
// example in Website, without this 'not', the 's_website_form' snippets
|
|
// with a black background in modals and on websites with a black
|
|
// background would have their input background changing from black to
|
|
// white.
|
|
// TODO: In Master, find a more consistent way to define the background
|
|
// color of 's_website_form' snippet inputs inside a modal.
|
|
&:where(:not(.oe_structure)) {
|
|
@if ($input-bg == $body-bg) {
|
|
.form-control {
|
|
background-color: $modal-content-bg;
|
|
color: color-contrast($modal-content-bg);
|
|
}
|
|
}
|
|
@if ($form-select-bg == $body-bg) {
|
|
.form-select {
|
|
background-color: $modal-content-bg;
|
|
color: color-contrast($modal-content-bg);;
|
|
}
|
|
}
|
|
@if $form-check-input-bg == $body-bg {
|
|
.form-check-input:not(:checked) {
|
|
background-color: $modal-content-bg;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.text-muted {
|
|
color: adjust-color-to-background($text-muted, $modal-content-bg, mute-color($color-contrast-light), mute-color($color-contrast-dark)) !important;
|
|
}
|
|
}
|
|
|
|
// Popover
|
|
.popover {
|
|
// The popover can have a different background color than that of the body.
|
|
// Here, we adjust the text color of the popover in case the body color
|
|
// (used by default for the text color of popovers) is not visible inside a
|
|
// popover due to a lack of contrast (e.g. on a website with a dark
|
|
// background).
|
|
@if $popover-header-color == null {
|
|
.popover-header {
|
|
color: adjust-color-to-background($body-color, $popover-header-bg);
|
|
}
|
|
}
|
|
@if $popover-body-color == $body-color {
|
|
.popover-body {
|
|
color: adjust-color-to-background($body-color, $popover-bg);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Form
|
|
.form-check-input {
|
|
// Without this line, the border of the checkboxes is not visible when the
|
|
// body is dark. This is due to the fact that the borders are defined based
|
|
// on the 'currentColor' of the inputs.
|
|
color: inherit;
|
|
}
|
|
.form-control.bg-light {
|
|
color: adjust-color-to-background($input-color, $light);
|
|
}
|
|
|
|
$-color-for-gray-200-bg: adjust-color-to-background($body-color, $gray-200);
|
|
// Input group text (e.g. Date time picker)
|
|
.input-group-text {
|
|
// Adapt only if the variables have their default values.
|
|
@if ($input-group-addon-bg == $gray-200) and ($input-group-addon-color == $body-color) {
|
|
color: $-color-for-gray-200-bg;
|
|
}
|
|
}
|
|
// File upload button
|
|
.form-control::file-selector-button {
|
|
@if ($form-file-button-bg == $gray-200) and ($form-file-button-color == $body-color) {
|
|
color: $-color-for-gray-200-bg;
|
|
}
|
|
}
|
|
|
|
// offcanvas
|
|
.offcanvas {
|
|
@if $offcanvas-color == null {
|
|
color: adjust-color-to-background($body-color, $offcanvas-bg-color);
|
|
|
|
@if $form-check-input-bg == $body-bg {
|
|
.form-check-input:where(:not(:checked)) {
|
|
background-color: $offcanvas-bg-color;
|
|
}
|
|
}
|
|
@if $form-range-thumb-bg == $body-bg {
|
|
.form-range {
|
|
&::-webkit-slider-thumb {
|
|
&:where(:not(:active)) {
|
|
background-color: $offcanvas-bg-color;
|
|
}
|
|
}
|
|
&::-moz-range-thumb {
|
|
&:where(:not(:active)) {
|
|
background-color: $offcanvas-bg-color;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Button within input-group (e.g., "search bar")
|
|
.input-group {
|
|
.btn:first-child, .btn:last-child {
|
|
@include border-radius($input-border-radius, 0);
|
|
}
|
|
}
|
|
|
|
// Dropdown
|
|
.dropdown .dropdown-menu {
|
|
.text-muted {
|
|
color: adjust-color-to-background($text-muted, $dropdown-bg, mute-color($color-contrast-light), mute-color($color-contrast-dark)) !important;
|
|
}
|
|
}
|
|
|
|
// The following code adapts the style of disabled inputs to maintain color
|
|
// consistency and make them more recognizable.
|
|
.form-select {
|
|
// This is necessary to achieve a consistent "border rendering behaviour"
|
|
// across form-select and form-control when using semi-transparent
|
|
// borders and a background color (eg. disabled inputs).
|
|
// Otherwise, the color rendering of the semi-transparent border may be altered
|
|
// (the color may be darker depending on the background color used).
|
|
background-clip: padding-box;
|
|
|
|
&:disabled:not([multiple]):where(:not([size]), [size="1"]) {
|
|
background-image: str-replace($form-select-indicator, #{$form-select-indicator-color}, str-replace(#{$form-select-disabled-color}, "#", "%23"));
|
|
}
|
|
}
|
|
|
|
.form-control {
|
|
&:disabled, &[readonly] {
|
|
color: $form-select-disabled-color;
|
|
}
|
|
}
|
|
|
|
.form-check-input:disabled:not(:checked) {
|
|
background-color: $input-disabled-bg;
|
|
|
|
.form-switch & {
|
|
background-image: escape-svg(url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'><circle r='3' fill='#{$form-select-disabled-color}'/></svg>"));
|
|
}
|
|
}
|
|
|
|
.form-range:disabled::-webkit-slider-thumb {
|
|
border-color: $input-disabled-border-color;
|
|
}
|