问题
I'm working on CSS for reasonably cross-browser native range slider. In Chrome the endpoints are fine but in Firefox they are cutoff. How can I normalize them to not be cut off in Firefox?
HTML
<fieldset class="range__field">
<input class="range is-stacking" type="range" min="0" max="10">
<svg class="range__axis is-stacking" role="presentation" width="100%" height="10" xmlns="http://www.w3.org/2000/svg">
<rect class="range__tick" x="0%" y="3" width="1" height="10"></rect>
<rect class="range__tick" x="10%" y="3" width="1" height="10"></rect>
<rect class="range__tick" x="20%" y="3" width="1" height="10"></rect>
<rect class="range__tick" x="30%" y="3" width="1" height="10"></rect>
<rect class="range__tick" x="40%" y="3" width="1" height="10"></rect>
<rect class="range__tick" x="50%" y="3" width="1" height="10"></rect>
<rect class="range__tick" x="60%" y="3" width="1" height="10"></rect>
<rect class="range__tick" x="70%" y="3" width="1" height="10"></rect>
<rect class="range__tick" x="80%" y="3" width="1" height="10"></rect>
<rect class="range__tick" x="90%" y="3" width="1" height="10"></rect>
<rect class="range__tick" x="100%" y="3" width="1" height="10"></rect>
</svg>
<svg class="range__axis is-stacking" role="presentation" width="100%" height="14" xmlns="http://www.w3.org/2000/svg">
<text class="range__point" x="0%" y="14" text-anchor="middle">0</text>
<text class="range__point" x="10%" y="14" text-anchor="middle">1</text>
<text class="range__point" x="20%" y="14" text-anchor="middle">2</text>
<text class="range__point" x="30%" y="14" text-anchor="middle">3</text>
<text class="range__point" x="40%" y="14" text-anchor="middle">4</text>
<text class="range__point" x="50%" y="14" text-anchor="middle">5</text>
<text class="range__point" x="60%" y="14" text-anchor="middle">6</text>
<text class="range__point" x="70%" y="14" text-anchor="middle">7</text>
<text class="range__point" x="80%" y="14" text-anchor="middle">8</text>
<text class="range__point" x="90%" y="14" text-anchor="middle">9</text>
<text class="range__point" x="100%" y="14" text-anchor="middle">10</text>
</svg>
</fieldset>
SCSS
*, :before, :after {
box-sizing: border-box;
}
@import "bourbon";
// Adapted from http://danielstern.ca/range.css
// Uses .range to target instead of [type="range"]
// Warning: Don't group vendor rules
$tick-color: silver;
$point-color: silver;
$endpoint-color: silver;
$value-color: blue;
$track-left-color: blue;
$track-right-color: silver;
$thumb-color: white;
$thumb-width: 20px;
$thumb-height: 20px;
$track-height: 5px;
$track-radius: $track-height / 2;
@function range-gradient($midpoint) {
@return linear-gradient(to right, $track-left-color $midpoint, $track-right-color 0);
}
@mixin range-track() {
width: 100%;
height: $track-height;
cursor: pointer;
box-shadow: 1px 1px 1px rgba(0, 0, 0, 0), 0px 0px 1px rgba(13, 13, 13, 0);
background: $track-left-color;
border-radius: $track-radius;
border: 0;
}
@mixin range-thumb() {
box-shadow: 1px 1px 1px black, 0px 0px 1px black;
border: 0;
height: $thumb-height;
width: $thumb-width;
border-radius: 50%;
background: $thumb-color;
cursor: pointer;
}
input.range {
-webkit-appearance: none;
position: relative;
width: 100%;
margin: 0;
padding: 0;
border: 0;
background: transparent;
// Stick the ticks to the range
@include transform(translateY(1em));
margin-top: -1em;
&:focus {
outline: 0;
}
// http://stackoverflow.com/a/24203354/770127
&::-moz-focus-outer {
border: 0;
}
}
input.range::-webkit-slider-thumb {
@include range-thumb;
-webkit-appearance: none;
// http://bitly.com/webkit-thumb-offset
margin-top: $track-height / 2 - $thumb-height / 2;
}
input.range::-moz-range-thumb {
@include range-thumb;
}
input.range::-webkit-slider-runnable-track {
@include range-track;
}
input.range::-moz-range-track {
@include range-track;
}
input.range::-ms-track {
width: 100%;
height: $track-height;
cursor: pointer;
background: transparent;
border-color: transparent;
color: transparent;
}
input.range::-ms-thumb {
@include range-thumb;
height: $track-height;
}
input.range::-ms-fill-lower,
input.range::-ms-fill-upper {
background: $track-left-color;
border: 0;
border-radius: $track-height;
box-shadow: 1px 1px 1px rgba(0, 0, 0, 0), 0px 0px 1px rgba(13, 13, 13, 0);
}
@if $track-left-color != $track-right-color {
@for $i from 0 through 10 {
input.range[data-range-value="#{$i}"] {
&::-webkit-slider-runnable-track {
@include background-image(range-gradient(percentage($i / 10)));
}
&::-moz-range-track {
@include background-image(range-gradient(percentage($i / 10)));
}
}
}
}
// Fit the axes to the range
// http://stackoverflow.com/a/40392411/770127
.range__axis {
padding-left: $thumb-width / 2;
padding-right: $thumb-width / 2;
}
.range__tick {
fill: $tick-color;
}
.range__point {
fill: $point-color;
}
// Endpoint color
@if $point-color != $endpoint-color {
.range__point:first-child,
.range__point:last-child {
fill: $endpoint-color;
}
}
// Current value color
@if $point-color != $value-color {
@for $i from 0 through 10 {
[data-range-percent="#{10 * $i}"] ~ svg .range__point[x="#{10 * $i}%"] {
fill: $value-color;
}
}
}
.range__field {
border: 0;
padding: 0;
}
回答1:
I guess the simplest answer is to add overflow="visible" to the second <svg>
element.
A better solution would be not to draw off the edge of the svg canvas in the first place though, i.e. move your text in from the edges a bit by starting at a value of x that is greater than 0% and finishing before 100%.
来源:https://stackoverflow.com/questions/40431972/range-slider-endpoints-are-cut-off-in-firefox