summaryrefslogtreecommitdiff
path: root/www/wiki/resources/src/mediawiki.ui/components/radio.less
blob: d9b7c6d301f89d38e60519655403e4ea42740e01 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
@import 'mediawiki.mixins';
@import 'mediawiki.ui/variables';

// Radio
//
// Styling radios in a way that works cross browser is a tricky problem to solve.
// In MediaWiki UI put a radio and label inside a mw-ui-radio div.
// This renders in all browsers except IE 6-8 which do not support the :checked selector;
// these are kept backwards-compatible using the `:not( #noop )` selector.
// You should give the radio and label matching "id" and "for" attributes, respectively.
//
// Markup:
// <div class="mw-ui-radio">
//   <input type="radio" id="kss-example-4" name="kss-example-4">
//   <label for="kss-example-4">Standard radio</label>
// </div>
// <div class="mw-ui-radio">
//   <input type="radio" id="kss-example-4-checked" name="kss-example-4" checked>
//   <label for="kss-example-4-checked">Standard checked radio</label>
// </div>
// <div class="mw-ui-radio">
//   <input type="radio" id="kss-example-4-disabled" name="kss-example-4-disabled" disabled>
//   <label for="kss-example-4-disabled">Disabled radio</label>
// </div>
// <div class="mw-ui-radio">
//   <input type="radio" id="kss-example-4-disabled-checked" name="kss-example-4-disabled" disabled checked>
//   <label for="kss-example-4-disabled-checked">Disabled checked radio</label>
// </div>
//
// Styleguide 4.
.mw-ui-radio {
	display: inline-block;
	vertical-align: middle;
}

// We use the not selector to cancel out styling on IE 8 and below.
// We also disable this styling on JavaScript disabled devices. This fixes the issue with
// Opera Mini where checking/unchecking doesn't apply styling but potentially leaves other
// more capable browsers with unstyled radio buttons.
.client-js .mw-ui-radio:not( #noop ) {
	// Position relatively so we can make use of absolute pseudo elements
	position: relative;
	line-height: @sizeInputBinary;

	* {
		// reset font sizes (see T74727)
		font: inherit;
		vertical-align: middle;
	}

	[ type='radio' ] {
		// ensure the invisible radio takes up the required width
		width: @sizeInputBinary;
		height: @sizeInputBinary;
		// This is needed for Firefox mobile (See T73750 to workaround default Firefox stylesheet)
		max-width: none;
		margin: 0;
		// Hide `input[ type=radio ]` and instead style the label that follows
		// Support: VoiceOver. Use `opacity` so that VoiceOver can still identify the radio
		opacity: 0;

		& + label {
			padding-left: 0.4em;

			// Pseudo `:before` element of the label after the radio now looks like a radio
			&:before {
				content: '';
				background-color: #fff;
				.box-sizing( border-box );
				position: absolute;
				left: 0;
				width: @sizeInputBinary;
				height: @sizeInputBinary;
				border: 1px solid @colorGray7;
				border-radius: 100%;
			}

			// Needed for `:focus` state's inner white circle
			&:after {
				content: ' ';
				position: absolute;
				top: 2px; // `px` unit due to pixel rounding error when using `@sizeInputBinary / 4`
				left: 2px;
				width: 1.14285em; // equals `@sizeInputBinary - 4px`
				height: 1.14285em;
				border: 1px solid transparent;
				border-radius: 100%;
			}
		}

		// Apply a dot on the pseudo `:before` element when the input is checked
		&:checked + label:before {
			border-width: @borderWidthRadioChecked;
		}

		&:enabled {
			cursor: pointer;

			& + label:before {
				cursor: pointer;
				.transition( ~'background-color 100ms, color 100ms, border-color 100ms' );
			}

			&:hover + label:before {
				border-color: @colorProgressive;
			}

			&:active + label:before {
				background-color: @colorProgressiveActive;
				border-color: @borderColorInputBinaryActive;
			}

			&:checked {
				& + label:before {
					border-color: @borderColorInputBinaryChecked;
				}

				&:focus + label:after {
					border-color: #fff;
				}

				&:hover + label:before {
					border-color: @colorProgressiveHighlight;
				}

				&:active {
					& + label:before {
						border-color: @borderColorInputBinaryActive;
						box-shadow: @boxShadowInputBinaryActive;
					}

					& + label:after {
						border-color: @borderColorInputBinaryActive;
					}
				}
			}
		}

		&:disabled {
			& + label:before {
				background-color: @colorGray12;
				border-color: @colorGray12;
			}

			&:checked + label:before {
				background-color: #fff;
			}
		}
	}
}