_custom-forms.scss 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523
  1. // Embedded icons from Open Iconic.
  2. // Released under MIT and copyright 2014 Waybury.
  3. // https://useiconic.com/open
  4. // Checkboxes and radios
  5. //
  6. // Base class takes care of all the key behavioral aspects.
  7. .custom-control {
  8. position: relative;
  9. z-index: 1;
  10. display: block;
  11. min-height: $font-size-base * $line-height-base;
  12. padding-left: $custom-control-gutter + $custom-control-indicator-size;
  13. }
  14. .custom-control-inline {
  15. display: inline-flex;
  16. margin-right: $custom-control-spacer-x;
  17. }
  18. .custom-control-input {
  19. position: absolute;
  20. left: 0;
  21. z-index: -1; // Put the input behind the label so it doesn't overlay text
  22. width: $custom-control-indicator-size;
  23. height: ($font-size-base * $line-height-base + $custom-control-indicator-size) / 2;
  24. opacity: 0;
  25. &:checked ~ .custom-control-label::before {
  26. color: $custom-control-indicator-checked-color;
  27. border-color: $custom-control-indicator-checked-border-color;
  28. @include gradient-bg($custom-control-indicator-checked-bg);
  29. @include box-shadow($custom-control-indicator-checked-box-shadow);
  30. }
  31. &:focus ~ .custom-control-label::before {
  32. // the mixin is not used here to make sure there is feedback
  33. @if $enable-shadows {
  34. box-shadow: $input-box-shadow, $input-focus-box-shadow;
  35. } @else {
  36. box-shadow: $custom-control-indicator-focus-box-shadow;
  37. }
  38. }
  39. &:focus:not(:checked) ~ .custom-control-label::before {
  40. border-color: $custom-control-indicator-focus-border-color;
  41. }
  42. &:not(:disabled):active ~ .custom-control-label::before {
  43. color: $custom-control-indicator-active-color;
  44. background-color: $custom-control-indicator-active-bg;
  45. border-color: $custom-control-indicator-active-border-color;
  46. @include box-shadow($custom-control-indicator-active-box-shadow);
  47. }
  48. // Use [disabled] and :disabled to work around https://github.com/twbs/bootstrap/issues/28247
  49. &[disabled],
  50. &:disabled {
  51. ~ .custom-control-label {
  52. color: $custom-control-label-disabled-color;
  53. &::before {
  54. background-color: $custom-control-indicator-disabled-bg;
  55. }
  56. }
  57. }
  58. }
  59. // Custom control indicators
  60. //
  61. // Build the custom controls out of pseudo-elements.
  62. .custom-control-label {
  63. position: relative;
  64. margin-bottom: 0;
  65. color: $custom-control-label-color;
  66. vertical-align: top;
  67. cursor: $custom-control-cursor;
  68. // Background-color and (when enabled) gradient
  69. &::before {
  70. position: absolute;
  71. top: ($font-size-base * $line-height-base - $custom-control-indicator-size) / 2;
  72. left: -($custom-control-gutter + $custom-control-indicator-size);
  73. display: block;
  74. width: $custom-control-indicator-size;
  75. height: $custom-control-indicator-size;
  76. pointer-events: none;
  77. content: "";
  78. background-color: $custom-control-indicator-bg;
  79. border: $custom-control-indicator-border-color solid $custom-control-indicator-border-width;
  80. @include box-shadow($custom-control-indicator-box-shadow);
  81. }
  82. // Foreground (icon)
  83. &::after {
  84. position: absolute;
  85. top: ($font-size-base * $line-height-base - $custom-control-indicator-size) / 2;
  86. left: -($custom-control-gutter + $custom-control-indicator-size);
  87. display: block;
  88. width: $custom-control-indicator-size;
  89. height: $custom-control-indicator-size;
  90. content: "";
  91. background: no-repeat 50% / #{$custom-control-indicator-bg-size};
  92. }
  93. }
  94. // Checkboxes
  95. //
  96. // Tweak just a few things for checkboxes.
  97. .custom-checkbox {
  98. .custom-control-label::before {
  99. @include border-radius($custom-checkbox-indicator-border-radius);
  100. }
  101. .custom-control-input:checked ~ .custom-control-label {
  102. &::after {
  103. background-image: escape-svg($custom-checkbox-indicator-icon-checked);
  104. }
  105. }
  106. .custom-control-input:indeterminate ~ .custom-control-label {
  107. &::before {
  108. border-color: $custom-checkbox-indicator-indeterminate-border-color;
  109. @include gradient-bg($custom-checkbox-indicator-indeterminate-bg);
  110. @include box-shadow($custom-checkbox-indicator-indeterminate-box-shadow);
  111. }
  112. &::after {
  113. background-image: escape-svg($custom-checkbox-indicator-icon-indeterminate);
  114. }
  115. }
  116. .custom-control-input:disabled {
  117. &:checked ~ .custom-control-label::before {
  118. @include gradient-bg($custom-control-indicator-checked-disabled-bg);
  119. }
  120. &:indeterminate ~ .custom-control-label::before {
  121. @include gradient-bg($custom-control-indicator-checked-disabled-bg);
  122. }
  123. }
  124. }
  125. // Radios
  126. //
  127. // Tweak just a few things for radios.
  128. .custom-radio {
  129. .custom-control-label::before {
  130. // stylelint-disable-next-line property-blacklist
  131. border-radius: $custom-radio-indicator-border-radius;
  132. }
  133. .custom-control-input:checked ~ .custom-control-label {
  134. &::after {
  135. background-image: escape-svg($custom-radio-indicator-icon-checked);
  136. }
  137. }
  138. .custom-control-input:disabled {
  139. &:checked ~ .custom-control-label::before {
  140. @include gradient-bg($custom-control-indicator-checked-disabled-bg);
  141. }
  142. }
  143. }
  144. // switches
  145. //
  146. // Tweak a few things for switches
  147. .custom-switch {
  148. padding-left: $custom-switch-width + $custom-control-gutter;
  149. .custom-control-label {
  150. &::before {
  151. left: -($custom-switch-width + $custom-control-gutter);
  152. width: $custom-switch-width;
  153. pointer-events: all;
  154. // stylelint-disable-next-line property-blacklist
  155. border-radius: $custom-switch-indicator-border-radius;
  156. }
  157. &::after {
  158. top: add(($font-size-base * $line-height-base - $custom-control-indicator-size) / 2, $custom-control-indicator-border-width * 2);
  159. left: add(-($custom-switch-width + $custom-control-gutter), $custom-control-indicator-border-width * 2);
  160. width: $custom-switch-indicator-size;
  161. height: $custom-switch-indicator-size;
  162. background-color: $custom-control-indicator-border-color;
  163. // stylelint-disable-next-line property-blacklist
  164. border-radius: $custom-switch-indicator-border-radius;
  165. @include transition(transform .15s ease-in-out, $custom-forms-transition);
  166. }
  167. }
  168. .custom-control-input:checked ~ .custom-control-label {
  169. &::after {
  170. background-color: $custom-control-indicator-bg;
  171. transform: translateX($custom-switch-width - $custom-control-indicator-size);
  172. }
  173. }
  174. .custom-control-input:disabled {
  175. &:checked ~ .custom-control-label::before {
  176. @include gradient-bg($custom-control-indicator-checked-disabled-bg);
  177. }
  178. }
  179. }
  180. // Select
  181. //
  182. // Replaces the browser default select with a custom one, mostly pulled from
  183. // https://primer.github.io/.
  184. //
  185. .custom-select {
  186. display: inline-block;
  187. width: 100%;
  188. height: $custom-select-height;
  189. padding: $custom-select-padding-y ($custom-select-padding-x + $custom-select-indicator-padding) $custom-select-padding-y $custom-select-padding-x;
  190. font-family: $custom-select-font-family;
  191. @include font-size($custom-select-font-size);
  192. font-weight: $custom-select-font-weight;
  193. line-height: $custom-select-line-height;
  194. color: $custom-select-color;
  195. vertical-align: middle;
  196. background: $custom-select-bg $custom-select-background;
  197. border: $custom-select-border-width solid $custom-select-border-color;
  198. @include border-radius($custom-select-border-radius, 0);
  199. @include box-shadow($custom-select-box-shadow);
  200. appearance: none;
  201. &:focus {
  202. border-color: $custom-select-focus-border-color;
  203. outline: 0;
  204. @if $enable-shadows {
  205. @include box-shadow($custom-select-box-shadow, $custom-select-focus-box-shadow);
  206. } @else {
  207. // Avoid using mixin so we can pass custom focus shadow properly
  208. box-shadow: $custom-select-focus-box-shadow;
  209. }
  210. &::-ms-value {
  211. // For visual consistency with other platforms/browsers,
  212. // suppress the default white text on blue background highlight given to
  213. // the selected option text when the (still closed) <select> receives focus
  214. // in IE and (under certain conditions) Edge.
  215. // See https://github.com/twbs/bootstrap/issues/19398.
  216. color: $input-color;
  217. background-color: $input-bg;
  218. }
  219. }
  220. &[multiple],
  221. &[size]:not([size="1"]) {
  222. height: auto;
  223. padding-right: $custom-select-padding-x;
  224. background-image: none;
  225. }
  226. &:disabled {
  227. color: $custom-select-disabled-color;
  228. background-color: $custom-select-disabled-bg;
  229. }
  230. // Hides the default caret in IE11
  231. &::-ms-expand {
  232. display: none;
  233. }
  234. // Remove outline from select box in FF
  235. &:-moz-focusring {
  236. color: transparent;
  237. text-shadow: 0 0 0 $custom-select-color;
  238. }
  239. }
  240. .custom-select-sm {
  241. height: $custom-select-height-sm;
  242. padding-top: $custom-select-padding-y-sm;
  243. padding-bottom: $custom-select-padding-y-sm;
  244. padding-left: $custom-select-padding-x-sm;
  245. @include font-size($custom-select-font-size-sm);
  246. }
  247. .custom-select-lg {
  248. height: $custom-select-height-lg;
  249. padding-top: $custom-select-padding-y-lg;
  250. padding-bottom: $custom-select-padding-y-lg;
  251. padding-left: $custom-select-padding-x-lg;
  252. @include font-size($custom-select-font-size-lg);
  253. }
  254. // File
  255. //
  256. // Custom file input.
  257. .custom-file {
  258. position: relative;
  259. display: inline-block;
  260. width: 100%;
  261. height: $custom-file-height;
  262. margin-bottom: 0;
  263. }
  264. .custom-file-input {
  265. position: relative;
  266. z-index: 2;
  267. width: 100%;
  268. height: $custom-file-height;
  269. margin: 0;
  270. opacity: 0;
  271. &:focus ~ .custom-file-label {
  272. border-color: $custom-file-focus-border-color;
  273. box-shadow: $custom-file-focus-box-shadow;
  274. }
  275. // Use [disabled] and :disabled to work around https://github.com/twbs/bootstrap/issues/28247
  276. &[disabled] ~ .custom-file-label,
  277. &:disabled ~ .custom-file-label {
  278. background-color: $custom-file-disabled-bg;
  279. }
  280. @each $lang, $value in $custom-file-text {
  281. &:lang(#{$lang}) ~ .custom-file-label::after {
  282. content: $value;
  283. }
  284. }
  285. ~ .custom-file-label[data-browse]::after {
  286. content: attr(data-browse);
  287. }
  288. }
  289. .custom-file-label {
  290. position: absolute;
  291. top: 0;
  292. right: 0;
  293. left: 0;
  294. z-index: 1;
  295. height: $custom-file-height;
  296. padding: $custom-file-padding-y $custom-file-padding-x;
  297. font-family: $custom-file-font-family;
  298. font-weight: $custom-file-font-weight;
  299. line-height: $custom-file-line-height;
  300. color: $custom-file-color;
  301. background-color: $custom-file-bg;
  302. border: $custom-file-border-width solid $custom-file-border-color;
  303. @include border-radius($custom-file-border-radius);
  304. @include box-shadow($custom-file-box-shadow);
  305. &::after {
  306. position: absolute;
  307. top: 0;
  308. right: 0;
  309. bottom: 0;
  310. z-index: 3;
  311. display: block;
  312. height: $custom-file-height-inner;
  313. padding: $custom-file-padding-y $custom-file-padding-x;
  314. line-height: $custom-file-line-height;
  315. color: $custom-file-button-color;
  316. content: "Browse";
  317. @include gradient-bg($custom-file-button-bg);
  318. border-left: inherit;
  319. @include border-radius(0 $custom-file-border-radius $custom-file-border-radius 0);
  320. }
  321. }
  322. // Range
  323. //
  324. // Style range inputs the same across browsers. Vendor-specific rules for pseudo
  325. // elements cannot be mixed. As such, there are no shared styles for focus or
  326. // active states on prefixed selectors.
  327. .custom-range {
  328. width: 100%;
  329. height: add($custom-range-thumb-height, $custom-range-thumb-focus-box-shadow-width * 2);
  330. padding: 0; // Need to reset padding
  331. background-color: transparent;
  332. appearance: none;
  333. &:focus {
  334. outline: none;
  335. // Pseudo-elements must be split across multiple rulesets to have an effect.
  336. // No box-shadow() mixin for focus accessibility.
  337. &::-webkit-slider-thumb { box-shadow: $custom-range-thumb-focus-box-shadow; }
  338. &::-moz-range-thumb { box-shadow: $custom-range-thumb-focus-box-shadow; }
  339. &::-ms-thumb { box-shadow: $custom-range-thumb-focus-box-shadow; }
  340. }
  341. &::-moz-focus-outer {
  342. border: 0;
  343. }
  344. &::-webkit-slider-thumb {
  345. width: $custom-range-thumb-width;
  346. height: $custom-range-thumb-height;
  347. margin-top: ($custom-range-track-height - $custom-range-thumb-height) / 2; // Webkit specific
  348. @include gradient-bg($custom-range-thumb-bg);
  349. border: $custom-range-thumb-border;
  350. @include border-radius($custom-range-thumb-border-radius);
  351. @include box-shadow($custom-range-thumb-box-shadow);
  352. @include transition($custom-forms-transition);
  353. appearance: none;
  354. &:active {
  355. @include gradient-bg($custom-range-thumb-active-bg);
  356. }
  357. }
  358. &::-webkit-slider-runnable-track {
  359. width: $custom-range-track-width;
  360. height: $custom-range-track-height;
  361. color: transparent; // Why?
  362. cursor: $custom-range-track-cursor;
  363. background-color: $custom-range-track-bg;
  364. border-color: transparent;
  365. @include border-radius($custom-range-track-border-radius);
  366. @include box-shadow($custom-range-track-box-shadow);
  367. }
  368. &::-moz-range-thumb {
  369. width: $custom-range-thumb-width;
  370. height: $custom-range-thumb-height;
  371. @include gradient-bg($custom-range-thumb-bg);
  372. border: $custom-range-thumb-border;
  373. @include border-radius($custom-range-thumb-border-radius);
  374. @include box-shadow($custom-range-thumb-box-shadow);
  375. @include transition($custom-forms-transition);
  376. appearance: none;
  377. &:active {
  378. @include gradient-bg($custom-range-thumb-active-bg);
  379. }
  380. }
  381. &::-moz-range-track {
  382. width: $custom-range-track-width;
  383. height: $custom-range-track-height;
  384. color: transparent;
  385. cursor: $custom-range-track-cursor;
  386. background-color: $custom-range-track-bg;
  387. border-color: transparent; // Firefox specific?
  388. @include border-radius($custom-range-track-border-radius);
  389. @include box-shadow($custom-range-track-box-shadow);
  390. }
  391. &::-ms-thumb {
  392. width: $custom-range-thumb-width;
  393. height: $custom-range-thumb-height;
  394. margin-top: 0; // Edge specific
  395. margin-right: $custom-range-thumb-focus-box-shadow-width; // Workaround that overflowed box-shadow is hidden.
  396. margin-left: $custom-range-thumb-focus-box-shadow-width; // Workaround that overflowed box-shadow is hidden.
  397. @include gradient-bg($custom-range-thumb-bg);
  398. border: $custom-range-thumb-border;
  399. @include border-radius($custom-range-thumb-border-radius);
  400. @include box-shadow($custom-range-thumb-box-shadow);
  401. @include transition($custom-forms-transition);
  402. appearance: none;
  403. &:active {
  404. @include gradient-bg($custom-range-thumb-active-bg);
  405. }
  406. }
  407. &::-ms-track {
  408. width: $custom-range-track-width;
  409. height: $custom-range-track-height;
  410. color: transparent;
  411. cursor: $custom-range-track-cursor;
  412. background-color: transparent;
  413. border-color: transparent;
  414. border-width: $custom-range-thumb-height / 2;
  415. @include box-shadow($custom-range-track-box-shadow);
  416. }
  417. &::-ms-fill-lower {
  418. background-color: $custom-range-track-bg;
  419. @include border-radius($custom-range-track-border-radius);
  420. }
  421. &::-ms-fill-upper {
  422. margin-right: 15px; // arbitrary?
  423. background-color: $custom-range-track-bg;
  424. @include border-radius($custom-range-track-border-radius);
  425. }
  426. &:disabled {
  427. &::-webkit-slider-thumb {
  428. background-color: $custom-range-thumb-disabled-bg;
  429. }
  430. &::-webkit-slider-runnable-track {
  431. cursor: default;
  432. }
  433. &::-moz-range-thumb {
  434. background-color: $custom-range-thumb-disabled-bg;
  435. }
  436. &::-moz-range-track {
  437. cursor: default;
  438. }
  439. &::-ms-thumb {
  440. background-color: $custom-range-thumb-disabled-bg;
  441. }
  442. }
  443. }
  444. .custom-control-label::before,
  445. .custom-file-label,
  446. .custom-select {
  447. @include transition($custom-forms-transition);
  448. }