Fonts, Custom Sliders And Browser Prefixes
Section overview
In this lesson, we'll take our tip calculator to the next level by adding a professional font from Google Fonts and creating custom-styled range sliders. You'll also learn about browser vendor prefixes to ensure your CSS works across different browsers.
Range sliders are one of the trickier form elements to style because browsers have different default appearances. To create a consistent, custom look, we need to use vendor prefixes to target specific browser rendering engines.
Understanding vendor prefixes
Before we start styling, it's important to understand what vendor prefixes are and why we need them.
Vendor prefixes are special CSS properties that browser makers use to implement experimental or browser-specific features. Common prefixes include:
-webkit-
for Safari, Orion, and GNOME-moz-
for Firefox-ms-
for older Internet Explorer and Edge versions
When styling range sliders, different browsers use different pseudo-elements to target the slider track (the line) and thumb (the draggable circle). This means we need to write CSS for each browser separately to ensure our custom styling works everywhere.
Adding a class to range inputs
Before we can style our sliders, we need to add a class to both range inputs in our HTML. This allows us to target them with CSS.
Update both range inputs to include class="range"
:
<!-- Tip slider -->
<input type="range" value="0" id="tipInput" class="range" />
<!-- Split slider -->
<input
type="range"
min="1"
max="10"
value="1"
id="splitInput"
class="range"
/>
- Adding the
range
class allows us to apply custom styling to both sliders at once. - We can now target these elements using
.range
in our CSS.
Adding Google Fonts
Google Fonts provides a free library of web fonts that you can use in your projects. Let's add the Roboto font to give our calculator a modern, professional look.
Selecting a font
- Visit Google Fonts
- Search for "Roboto"
- Select the following styles:
- Light 300 (regular)
- Regular 400 (italic)
- Bold 700 (regular)
- Copy the
<link>
code provided
Linking the font
Add the Google Fonts stylesheet link in your <head>
section, before your styles.css
link:
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<link
href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,300;0,700;1,400&display=swap"
rel="stylesheet"
/>
<link rel="stylesheet" href="styles.css" />
<title>Quick Tip</title>
</head>
- The Google Fonts link must come before your stylesheet so the font is available when the CSS loads.
- The
display=swap
parameter ensures text remains visible while the font loads.
Applying the font
Now update your CSS to use the Roboto font. Modify the html
rule at the top of your styles.css
:
html {
font-family: "Roboto", sans-serif;
font-size: 10px;
color: #4e4d4d;
}
font-family: "Roboto", sans-serif
applies the Google Font first, with a sans-serif fallback.- It's best practice to place
font-family
first so if the font fails to load, the fallback is already defined. - The
sans-serif
fallback ensures text displays in a system font if Roboto fails to load.
Styling the range sliders
Now we'll create custom styles for our range sliders using the .range
class we added earlier. This is where vendor prefixes become essential.
Add the following CSS to your styles.css
file, below the .total
styles:
.range {
-webkit-appearance: none;
width: 100%;
height: 8px;
margin-top: 1.2rem;
background: #eee;
border-radius: 0.3rem;
outline-color: #5bceae;
}
-webkit-appearance: none
removes default WebKit browser styling so we can apply our custom styles.width: 100%
makes the slider fill its container width.height: 8px
sets the height of the slider track.margin-top: 1.2rem
adds some space above the slider.background: #eee
gives the track a light gray background.border-radius: 0.3rem
slightly rounds the track corners.outline-color: #5bceae
sets the focus outline color to match our theme (for when using keyboard navigation).
Styling the slider thumb for WebKit browsers
The thumb is the circular handle that users drag along the track. Let's style it for WebKit browsers:
.range::-webkit-slider-thumb {
-webkit-appearance: none;
width: 2.2rem;
height: 2.2rem;
border-radius: 50%;
background: #3dc0c0;
cursor: pointer;
}
::-webkit-slider-thumb
is a pseudo-element that targets the draggable thumb in WebKit browsers.-webkit-appearance: none
removes the default thumb styling.width
andheight
set to2.2rem
(22px) creates a reasonably sized circle.border-radius: 50%
creates a perfect circle.background: #3dc0c0
uses our teal color from the gradient.cursor: pointer
shows a pointer cursor when hovering over the thumb.
Styling the slider thumb for Firefox
Firefox uses a different pseudo-element to target the thumb, so we need separate styling:
.range::-moz-range-thumb {
width: 2.2rem;
height: 2.2rem;
border-radius: 50%;
background: #3dc0c0;
cursor: pointer;
border: 0;
}
::-moz-range-thumb
targets the thumb in Firefox browsers.- The sizing and styling matches the WebKit version for consistency.
border: 0
removes default border around the thumb.
Removing Firefox's focus outline
Firefox applies an additional outline around focused range inputs. Let's remove it to match our custom styling:
.range::-moz-focus-outer {
border: 0;
}
::-moz-focus-outer
is a Firefox-specific pseudo-element.border: 0
removes the dotted focus outline that Firefox adds by default.- Our custom
outline-color
on the.range
class will provide the focus indication instead.
Final HTML code
Here's the complete HTML for the Quick Tip calculator with all our updates:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<link
href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,300;0,700;1,400&display=swap"
rel="stylesheet"
/>
<link rel="stylesheet" href="styles.css" />
<title>Quick Tip</title>
</head>
<body>
<main id="container">
<h1>Quick Tip</h1>
<section>
<div class="bill">
<label for="yourBill">Bill</label>
<input type="number" placeholder="Your bill" id="yourBill" />
</div>
<div>
<div class="space-between">
<label for="tipInput">Select tip</label
><span id="tipPercent"></span>
</div>
<input type="range" value="0" id="tipInput" class="range" />
</div>
<div class="space-between">
<span>Tip</span>
<span id="tipValue"></span>
</div>
<hr />
<div class="space-between total">
<span>Total</span>
<span id="totalWithTip"></span>
</div>
</section>
<section>
<div>
<div class="space-between">
<label for="splitInput">Split</label>
<span id="splitValue"></span>
</div>
<input
type="range"
min="1"
max="10"
value="1"
id="splitInput"
class="range"
/>
</div>
<div class="space-between">
<span>Bill each</span>
<span id="billEach"></span>
</div>
<div class="space-between">
<span>Tip each</span>
<span id="tipEach"></span>
</div>
</section>
</main>
</body>
</html>
Final CSS code
Here's the complete CSS with all the new styling for fonts and custom sliders:
html {
font-family: "Roboto", sans-serif;
font-size: 10px;
color: #4e4d4d;
}
main {
max-width: 50rem;
margin: 2rem auto;
padding: 3rem 1.6rem 6rem 1.6rem;
background: linear-gradient(30deg, #3dc0c0, #5bceae);
border-radius: 4rem;
box-shadow: 0 2px 2px lightgray;
}
h1 {
text-align: center;
font-size: 3rem;
margin: 0;
padding-bottom: 3rem;
}
section {
background-color: white;
font-size: 1.8rem;
margin-bottom: 1.6rem;
padding: 0 1.6rem;
border-radius: 1rem;
box-shadow: inset 0 2px 2px lightgray;
}
section > div {
padding: 1.6rem 0;
}
.bill {
display: flex;
}
.bill label {
flex: 1;
align-self: center;
}
.bill input {
flex: 3;
}
input[type="number"] {
font-family: inherit;
background: #f4f4f5;
font-size: 1.6rem;
border: 1px solid lightgray;
border-radius: 0.5rem;
padding: 0.8rem 0 0.8rem 1rem;
box-shadow: inset 0 2px 2px lightgray;
}
.space-between {
display: flex;
justify-content: space-between;
}
.total {
font-size: 2rem;
font-weight: bolder;
}
.range {
-webkit-appearance: none;
width: 100%;
height: 8px;
margin-top: 1.2rem;
background: #eee;
border-radius: 0.3rem;
outline-color: #5bceae;
}
.range::-webkit-slider-thumb {
-webkit-appearance: none;
width: 2.2rem;
height: 2.2rem;
border-radius: 50%;
background: #3dc0c0;
cursor: pointer;
}
.range::-moz-range-thumb {
width: 2.2rem;
height: 2.2rem;
border-radius: 50%;
background: #3dc0c0;
cursor: pointer;
border: 0;
}
.range::-moz-focus-outer {
border: 0;
}
Summary
In this lesson, you learned how to:
- Add custom fonts from Google Fonts to enhance your project's typography
- Understand what vendor prefixes are and why they're needed for cross-browser compatibility
- Remove default range input styling using
-webkit-appearance: none
- Use the
::-webkit-slider-thumb
pseudo-element to style sliders - Use the
::-moz-range-thumb
pseudo-element to style sliders in Firefox - Handle Firefox-specific styling quirks with
::-moz-focus-outer
- Create consistent custom slider designs across different browsers
Custom range sliders can be tricky due to browser differences, but understanding vendor prefixes gives you the power to create consistent, beautiful interfaces across all browsers. The key is writing separate styles for WebKit-based browsers and Firefox to ensure your design looks the same everywhere.