_custom-forms.scss 15 KB

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