Use escape-svg() function (#29077)

* Use escape-svg() function

* Update theming.md
This commit is contained in:
Martijn Cuppens 2019-07-20 03:57:12 +02:00 committed by Mark Otto
parent 28dfa54083
commit f6694b7440
9 changed files with 51 additions and 31 deletions

View File

@ -17,7 +17,7 @@
display: inline-block; // Suppress underlining of the separator in modern browsers
padding-right: $breadcrumb-item-padding-x;
color: $breadcrumb-divider-color;
content: $breadcrumb-divider;
content: escape-svg($breadcrumb-divider);
}
}

View File

@ -131,10 +131,10 @@
background: no-repeat 50% / 100% 100%;
}
.carousel-control-prev-icon {
background-image: $carousel-control-prev-icon-bg;
background-image: escape-svg($carousel-control-prev-icon-bg);
}
.carousel-control-next-icon {
background-image: $carousel-control-next-icon-bg;
background-image: escape-svg($carousel-control-next-icon-bg);
}

View File

@ -71,6 +71,17 @@
@return $string;
}
// See https://codepen.io/kevinweber/pen/dXWoRw
@function escape-svg($string) {
@if str-index($string, "data:image/svg+xml") {
@each $char, $encoded in $escaped-characters {
$string: str-replace($string, $char, $encoded);
}
}
@return $string;
}
// Color contrast
@function color-yiq($color, $dark: $yiq-text-dark, $light: $yiq-text-light) {
$r: red($color);

View File

@ -229,7 +229,7 @@
}
.navbar-toggler-icon {
background-image: $navbar-light-toggler-icon-bg;
background-image: escape-svg($navbar-light-toggler-icon-bg);
}
.navbar-text {
@ -282,7 +282,7 @@
}
.navbar-toggler-icon {
background-image: $navbar-dark-toggler-icon-bg;
background-image: escape-svg($navbar-dark-toggler-icon-bg);
}
.navbar-text {

View File

@ -101,6 +101,12 @@ $yiq-contrasted-threshold: 150 !default;
$yiq-text-dark: $gray-900 !default;
$yiq-text-light: $white !default;
// Characters which are escaped by the escape-svg function
$escaped-characters: (
("<","%3c"),
(">","%3e"),
("#","%23"),
) !default;
// Options
//
@ -531,8 +537,8 @@ $form-check-input-checked-border-color: $form-check-input-checked-bg-color !de
$form-check-input-checked-bg-repeat: no-repeat !default;
$form-check-input-checked-bg-position: center center !default;
$form-check-input-checked-bg-size: 1em !default;
$form-check-input-checked-bg-image: str-replace(url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath stroke='#{$form-check-input-checked-color}' stroke-width='3' d='M4 8.5L6.5 11l6-6' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3e%3c/svg%3e"), "#", "%23") !default;
$form-check-radio-checked-bg-image: str-replace(url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='#{$form-check-input-checked-color}'/%3e%3c/svg%3e"), "#", "%23") !default;
$form-check-input-checked-bg-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path stroke='#{$form-check-input-checked-color}' stroke-width='3' d='M4 8.5L6.5 11l6-6' fill='none' stroke-linecap='round' stroke-linejoin='round'/></svg>") !default;
$form-check-radio-checked-bg-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'><circle r='3' fill='#{$form-check-input-checked-color}'/></svg>") !default;
$form-check-input-indeterminate-color: $component-active-color !default;
$form-check-input-indeterminate-bg-color: $component-active-bg !default;
@ -540,23 +546,23 @@ $form-check-input-indeterminate-border-color: $form-check-input-indeterminate-
$form-check-input-indeterminate-bg-repeat: no-repeat !default;
$form-check-input-indeterminate-bg-position: center center !default;
$form-check-input-indeterminate-bg-size: 1em !default;
$form-check-input-indeterminate-bg-image: str-replace(url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath d='M5 8h6' stroke='#{$form-check-input-indeterminate-color}' stroke-width='3' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3e%3c/svg%3e"), "#", "%23") !default;
$form-check-input-indeterminate-bg-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path d='M5 8h6' stroke='#{$form-check-input-indeterminate-color}' stroke-width='3' fill='none' stroke-linecap='round' stroke-linejoin='round'/></svg>") !default;
$form-switch-color: rgba(0, 0, 0, .25) !default;
$form-switch-width: 2em !default;
$form-switch-height: $form-check-input-width !default;
$form-switch-padding-left: $form-switch-width + .5em !default;
$form-switch-bg-image: str-replace(url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='#{$form-switch-color}'/%3e%3c/svg%3e"), "#", "%23") !default;
$form-switch-bg-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'><circle r='3' fill='#{$form-switch-color}'/></svg>") !default;
$form-switch-border-radius: $form-switch-width !default;
$form-switch-transition: .2s ease-in-out !default;
$form-switch-transition-property: background-position, background-color !default;
$form-switch-focus-color: hsla(211, 100%, 75%, 1) !default;
$form-switch-focus-bg-image: str-replace(url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='#{$form-switch-focus-color}'/%3e%3c/svg%3e"), "#", "%23") !default;
$form-switch-focus-bg-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'><circle r='3' fill='#{$form-switch-focus-color}'/></svg>") !default;
$form-switch-checked-color: $component-active-color !default;
$form-switch-checked-bg-image: str-replace(url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='#{$form-switch-checked-color}'/%3e%3c/svg%3e"), "#", "%23") !default;
$form-switch-checked-bg-position: right center !default;
$form-switch-checked-bg-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'><circle r='3' fill='#{$form-switch-checked-color}'/></svg>") !default;
$form-switch-checked-bg-position: right center !default;
$form-text-margin-top: .25rem !default;
@ -586,9 +592,9 @@ $form-select-bg: $input-bg !default;
$form-select-disabled-bg: $gray-200 !default;
$form-select-bg-size: 16px 12px !default; // In pixels because image dimensions
$form-select-indicator-color: $gray-800 !default;
$form-select-indicator: str-replace(url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath stroke='#{$form-select-indicator-color}' stroke-width='2px' d='M2 5l6 6 6-6' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3e%3c/svg%3e"), "#", "%23") !default;
$form-select-indicator: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path stroke='#{$form-select-indicator-color}' stroke-width='2px' d='M2 5l6 6 6-6' fill='none' stroke-linecap='round' stroke-linejoin='round'/></svg>") !default;
$form-select-background: $form-select-indicator no-repeat right $form-select-padding-x center / $form-select-bg-size !default; // Used so we can have multiple background elements (e.g., arrow and feedback icon)
$form-select-background: no-repeat right $form-select-padding-x center / $form-select-bg-size !default; // Used so we can have multiple background elements (e.g., arrow and feedback icon)
$form-select-feedback-icon-padding-right: calc((1em + #{2 * $form-select-padding-y}) * 3 / 4 + #{$form-select-padding-x + $form-select-indicator-padding}) !default;
$form-select-feedback-icon-position: center right ($form-select-padding-x + $form-select-indicator-padding) !default;
@ -659,9 +665,9 @@ $form-feedback-valid-color: theme-color("success") !default;
$form-feedback-invalid-color: theme-color("danger") !default;
$form-feedback-icon-valid-color: $form-feedback-valid-color !default;
$form-feedback-icon-valid: str-replace(url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='#{$form-feedback-icon-valid-color}' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e"), "#", "%23") !default;
$form-feedback-icon-valid: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'><path fill='#{$form-feedback-icon-valid-color}' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/></svg>") !default;
$form-feedback-icon-invalid-color: $form-feedback-invalid-color !default;
$form-feedback-icon-invalid: str-replace(url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' stroke='#{$form-feedback-icon-invalid-color}' fill='none'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath d='M5.8 3.6h.4L6 6.5z' stroke-linejoin='round'/%3e%3ccircle cx='6' cy='8.2' r='.1'/%3e%3c/svg%3e"), "#", "%23") !default;
$form-feedback-icon-invalid: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' stroke='#{$form-feedback-icon-invalid-color}' fill='none'><circle cx='6' cy='6' r='4.5'/><path d='M5.8 3.6h.4L6 6.5z' stroke-linejoin='round'/><circle cx='6' cy='8.2' r='.1'/></svg>") !default;
$form-validation-states: () !default;
// stylelint-disable-next-line scss/dollar-variable-default
@ -737,14 +743,14 @@ $navbar-dark-color: rgba($white, .5) !default;
$navbar-dark-hover-color: rgba($white, .75) !default;
$navbar-dark-active-color: $white !default;
$navbar-dark-disabled-color: rgba($white, .25) !default;
$navbar-dark-toggler-icon-bg: str-replace(url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='#{$navbar-dark-color}' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e"), "#", "%23") !default;
$navbar-dark-toggler-icon-bg: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'><path stroke='#{$navbar-dark-color}' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/></svg>") !default;
$navbar-dark-toggler-border-color: rgba($white, .1) !default;
$navbar-light-color: rgba($black, .5) !default;
$navbar-light-hover-color: rgba($black, .7) !default;
$navbar-light-active-color: rgba($black, .9) !default;
$navbar-light-disabled-color: rgba($black, .3) !default;
$navbar-light-toggler-icon-bg: str-replace(url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='#{$navbar-light-color}' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e"), "#", "%23") !default;
$navbar-light-toggler-icon-bg: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'><path stroke='#{$navbar-light-color}' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/></svg>") !default;
$navbar-light-toggler-border-color: rgba($black, .1) !default;
$navbar-light-brand-color: $navbar-light-active-color !default;
@ -1066,8 +1072,8 @@ $carousel-caption-color: $white !default;
$carousel-control-icon-width: 20px !default;
$carousel-control-prev-icon-bg: str-replace(url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='#{$carousel-control-color}' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3e%3c/svg%3e"), "#", "%23") !default;
$carousel-control-next-icon-bg: str-replace(url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='#{$carousel-control-color}' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3e%3c/svg%3e"), "#", "%23") !default;
$carousel-control-prev-icon-bg: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' fill='#{$carousel-control-color}' viewBox='0 0 8 8'><path d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/></svg>") !default;
$carousel-control-next-icon-bg: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' fill='#{$carousel-control-color}' viewBox='0 0 8 8'><path d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/></svg>") !default;
$carousel-transition-duration: .6s !default;
$carousel-transition: transform $carousel-transition-duration ease-in-out !default; // Define transform transition first if using multiple transitions (e.g., `transform 2s ease, opacity .5s ease-out`)

View File

@ -46,17 +46,17 @@
border-color: $form-check-input-checked-border-color;
&[type="checkbox"] {
background-image: $form-check-input-checked-bg-image;
background-image: escape-svg($form-check-input-checked-bg-image);
}
&[type="radio"] {
background-image: $form-check-radio-checked-bg-image;
background-image: escape-svg($form-check-radio-checked-bg-image);
}
}
&[type="checkbox"]:indeterminate {
background-color: $form-check-input-indeterminate-bg-color;
background-image: $form-check-input-indeterminate-bg-image;
background-image: escape-svg($form-check-input-indeterminate-bg-image);
background-repeat: $form-check-input-indeterminate-bg-repeat;
background-position: $form-check-input-indeterminate-bg-position;
background-size: $form-check-input-indeterminate-bg-size;
@ -90,7 +90,7 @@
.form-check-input {
width: $form-switch-width;
margin-left: $form-switch-padding-left * -1;
background-image: $form-switch-bg-image;
background-image: escape-svg($form-switch-bg-image);
background-repeat: no-repeat;
background-position: left center;
background-size: calc(#{$form-switch-height} - 2px); // Get a 1px separation
@ -100,11 +100,11 @@
// transition-property: $form-switch-transition-property;
&:focus {
background-image: $form-switch-focus-bg-image;
background-image: escape-svg($form-switch-focus-bg-image);
}
&:checked {
background-image: $form-switch-checked-bg-image;
background-image: escape-svg($form-switch-checked-bg-image);
background-position: $form-switch-checked-bg-position;
}
}

View File

@ -14,8 +14,7 @@
line-height: $form-select-line-height;
color: $form-select-color;
vertical-align: middle;
background: $form-select-background;
background-color: $form-select-bg;
background: $form-select-bg escape-svg($form-select-indicator) $form-select-background;
border: $form-select-border-width solid $form-select-border-color;
@include border-radius($form-select-border-radius, 0);
@include box-shadow($form-select-box-shadow);

View File

@ -69,7 +69,7 @@
@if $enable-validation-icons {
padding-right: $input-height-inner;
background-image: $icon;
background-image: escape-svg($icon);
background-repeat: no-repeat;
background-position: right $input-height-inner-quarter center;
background-size: $input-height-inner-half $input-height-inner-half;
@ -103,7 +103,7 @@
@if $enable-validation-icons {
padding-right: $form-select-feedback-icon-padding-right;
background: $form-select-background, $icon $form-select-bg no-repeat $form-select-feedback-icon-position / $form-select-feedback-icon-size;
background: escape-svg($form-select-indicator) $form-select-background, escape-svg($icon) $form-select-bg no-repeat $form-select-feedback-icon-position / $form-select-feedback-icon-size;
}
&:focus {

View File

@ -195,7 +195,7 @@ Additional functions could be added in the future or your own custom Sass to cre
### Color contrast
One additional function we include in Bootstrap is the color contrast function, `color-yiq`. It utilizes the [YIQ color space](https://en.wikipedia.org/wiki/YIQ) to automatically return a light (`#fff`) or dark (`#111`) contrast color based on the specified base color. This function is especially useful for mixins or loops where you're generating multiple classes.
An additional function we include in Bootstrap is the color contrast function, `color-yiq`. It utilizes the [YIQ color space](https://en.wikipedia.org/wiki/YIQ) to automatically return a light (`#fff`) or dark (`#111`) contrast color based on the specified base color. This function is especially useful for mixins or loops where you're generating multiple classes.
For example, to generate color swatches from our `$theme-colors` map:
@ -223,6 +223,10 @@ You can also specify a base color with our color map functions:
}
{{< /highlight >}}
## Escape SVG
We use the `escape-svg` function to escape the `<`, `>` and `#` characters for SVG background images. These characters need to be escaped to properly render the background images in IE.
## Sass options
Customize Bootstrap 4 with our built-in custom variables file and easily toggle global CSS preferences with new `$enable-*` Sass variables. Override a variable's value and recompile with `npm run test` as needed.