@import "../../settings/all"; @import "../../tools/all"; @import "../../helpers/all"; @import "../error-message/error-message"; @import "../fieldset/fieldset"; @import "../hint/hint"; @import "../label/label"; @include govuk-exports("govuk/component/checkboxes") { $govuk-touch-target-size: 44px; $govuk-checkboxes-size: 40px; $govuk-small-checkboxes-size: 24px; $govuk-checkboxes-label-padding-left-right: govuk-spacing(3); .govuk-checkboxes__item { @include govuk-font($size: 19); display: block; position: relative; min-height: $govuk-checkboxes-size; margin-bottom: govuk-spacing(2); padding-left: $govuk-checkboxes-size; clear: left; } .govuk-checkboxes__item:last-child, .govuk-checkboxes__item:last-of-type { margin-bottom: 0; } .govuk-checkboxes__input { $input-offset: ($govuk-touch-target-size - $govuk-checkboxes-size) / 2; cursor: pointer; // IE8 doesn’t support pseudo-elements, so we don’t want to hide native // elements there. @include govuk-not-ie8 { position: absolute; z-index: 1; top: $input-offset * -1; left: $input-offset * -1; width: $govuk-touch-target-size; height: $govuk-touch-target-size; margin: 0; opacity: 0; } @include govuk-if-ie8 { margin-top: 10px; margin-right: $govuk-checkboxes-size / -2; margin-left: $govuk-checkboxes-size / -2; float: left; // add focus outline to input &:focus { outline: $govuk-focus-width solid $govuk-focus-colour; } } } .govuk-checkboxes__label { display: inline-block; margin-bottom: 0; padding: 8px $govuk-checkboxes-label-padding-left-right govuk-spacing(1); cursor: pointer; // remove 300ms pause on mobile -ms-touch-action: manipulation; touch-action: manipulation; } // [ ] Check box .govuk-checkboxes__label::before { content: ""; box-sizing: border-box; position: absolute; top: 0; left: 0; width: $govuk-checkboxes-size; height: $govuk-checkboxes-size; border: $govuk-border-width-form-element solid currentColor; background: transparent; } // ✔ Check mark // // The check mark is a box with a border on the left and bottom side (└──), // rotated 45 degrees .govuk-checkboxes__label::after { content: ""; position: absolute; top: 11px; left: 9px; width: 18px; height: 7px; -webkit-transform: rotate(-45deg); -ms-transform: rotate(-45deg); transform: rotate(-45deg); border: solid; border-width: 0 0 $govuk-border-width $govuk-border-width; // Fix bug in IE11 caused by transform rotate (-45deg). // See: alphagov/govuk_elements/issues/518 border-top-color: transparent; opacity: 0; background: transparent; } .govuk-checkboxes__hint { display: block; padding-right: $govuk-checkboxes-label-padding-left-right; padding-left: $govuk-checkboxes-label-padding-left-right; } // Focused state .govuk-checkboxes__input:focus + .govuk-checkboxes__label::before { // Since box-shadows are removed when users customise their colours, we set // a transparent outline that is shown instead. // https://accessibility.blog.gov.uk/2017/03/27/how-users-change-colours-on-websites/ outline: $govuk-focus-width solid transparent; outline-offset: $govuk-focus-width; box-shadow: 0 0 0 $govuk-focus-width $govuk-focus-colour; } // Selected state .govuk-checkboxes__input:checked + .govuk-checkboxes__label::after { opacity: 1; } // Disabled state .govuk-checkboxes__input:disabled, .govuk-checkboxes__input:disabled + .govuk-checkboxes__label { cursor: default; } .govuk-checkboxes__input:disabled + .govuk-checkboxes__label { opacity: .5; } // ========================================================= // Conditional reveals // ========================================================= $conditional-border-width: $govuk-border-width-mobile; // Calculate the amount of padding needed to keep the border centered against the checkbox. $conditional-border-padding: ($govuk-checkboxes-size / 2) - ($conditional-border-width / 2); // Move the border centered with the checkbox $conditional-margin-left: $conditional-border-padding; // Move the contents of the conditional inline with the label $conditional-padding-left: $conditional-border-padding + $govuk-checkboxes-label-padding-left-right; .govuk-checkboxes__conditional { @include govuk-responsive-margin(4, "bottom"); margin-left: $conditional-margin-left; padding-left: $conditional-padding-left; border-left: $conditional-border-width solid $govuk-border-colour; .js-enabled &--hidden { display: none; } & > :last-child { margin-bottom: 0; } } // ========================================================= // Small checkboxes // ========================================================= .govuk-checkboxes--small { $input-offset: ($govuk-touch-target-size - $govuk-small-checkboxes-size) / 2; $label-offset: $govuk-touch-target-size - $input-offset; .govuk-checkboxes__item { @include govuk-clearfix; min-height: 0; margin-bottom: 0; padding-left: $label-offset; float: left; } // Shift the touch target into the left margin so that the visible edge of // the control is aligned // // ┆What colours do you like? // ┌┆───┐ // │┆[] │ Purple // └┆▲──┘ // ▲┆└─ Check box pseudo element, aligned with margin // └─── Touch target (invisible input), shifted into the margin .govuk-checkboxes__input { @include govuk-not-ie8 { left: $input-offset * -1; } @include govuk-if-ie8 { margin-left: $govuk-small-checkboxes-size * -1; } } // Adjust the size and position of the label. // // Unlike larger checkboxes, we also have to float the label in order to // 'shrink' it, preventing the hover state from kicking in across the full // width of the parent element. .govuk-checkboxes__label { margin-top: -2px; padding: 13px govuk-spacing(3) 13px 1px; float: left; @include govuk-media-query($from: tablet) { padding: 11px govuk-spacing(3) 10px 1px; } } // [ ] Check box // // Reduce the size of the check box [1], vertically center it within the // touch target [2] .govuk-checkboxes__label::before { top: $input-offset - $govuk-border-width-form-element; // 2 width: $govuk-small-checkboxes-size; // 1 height: $govuk-small-checkboxes-size; // 1 } // ✔ Check mark // // Reduce the size of the check mark and re-align within the checkbox .govuk-checkboxes__label::after { top: 15px; left: 6px; width: 9px; height: 3.5px; border-width: 0 0 3px 3px; } // Fix position of hint with small checkboxes // // Do not use hints with small checkboxes – because they're within the input // wrapper they trigger the hover state, but clicking them doesn't actually // activate the control. // // (If you do use them, they won't look completely broken... but seriously, // don't use them) .govuk-checkboxes__hint { padding: 0; clear: both; } // Align conditional reveals with small checkboxes .govuk-checkboxes__conditional { $margin-left: ($govuk-small-checkboxes-size / 2) - ($conditional-border-width / 2); margin-left: $margin-left; padding-left: $label-offset - ($margin-left + $conditional-border-width); clear: both; } // Hover state for small checkboxes. // // We use a hover state for small checkboxes because the touch target size // is so much larger than their visible size, and so we need to provide // feedback to the user as to which checkbox they will select when their // cursor is outside of the visible area. .govuk-checkboxes__item:hover .govuk-checkboxes__input:not(:disabled) + .govuk-checkboxes__label::before { box-shadow: 0 0 0 $govuk-hover-width $govuk-hover-colour; } // Because we've overridden the border-shadow provided by the focus state, // we need to redefine that too. // // We use two box shadows, one that restores the original focus state [1] // and another that then applies the hover state [2]. .govuk-checkboxes__item:hover .govuk-checkboxes__input:focus + .govuk-checkboxes__label::before { // sass-lint:disable indentation box-shadow: 0 0 0 $govuk-focus-width $govuk-focus-colour, // 1 0 0 0 $govuk-hover-width $govuk-hover-colour; // 2 } // For devices that explicitly don't support hover, don't provide a hover // state (e.g. on touch devices like iOS). // // We can't use `@media (hover: hover)` because we wouldn't get the hover // state in browsers that don't support `@media (hover)` (like Internet // Explorer) – so we have to 'undo' the hover state instead. @media (hover: none), (pointer: coarse) { .govuk-checkboxes__item:hover .govuk-checkboxes__input:not(:disabled) + .govuk-checkboxes__label::before { box-shadow: initial; } .govuk-checkboxes__item:hover .govuk-checkboxes__input:focus + .govuk-checkboxes__label::before { box-shadow: 0 0 0 $govuk-focus-width $govuk-focus-colour; } } } }