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