<!--
https://www.economicshelp.org/macroeconomics/monetary-policy/effect-raising-interest-rates/
https://www.npr.org/2019/07/30/746744003/stacey-vs-cardiff-the-fed-cut-throwdown
-->
<main class="wrapper">
<div class="top-row">
<h1>interest rates</h1>
<div id='volume' class='slider'>
<output class='slider-output'>50</output>
<div class='slider-track'>
<div class='slider-thumb'></div>
<div class='slider-level'></div>
</div>
<input class='slider-input' type='range' value='50' min='0' max='100' />
</div>
</div>
<div class="outer-row">
<div class="col">
<div class="inner-row">
<p class="bar-title">cost of borrowing</p>
<div class="bar">
<div class="fill fill_analogous"></div>
</div>
</div>
<div class="inner-row">
<p class="bar-title">mortgage interest payments</p>
<div class="bar">
<div class="fill fill_analogous"></div>
</div>
</div>
<div class="inner-row">
<p class="bar-title">savings rates</p>
<div class="bar">
<div class="fill fill_analogous"></div>
</div>
</div>
<div class="inner-row">
<p class="bar-title">exchange rates</p>
<div class="bar">
<div class="fill fill_analogous"></div>
</div>
</div>
</div>
<div class="col">
<div class="inner-row">
<p class="bar-title">employment</p>
<div class="bar">
<div class="fill fill_inverse"></div>
</div>
</div>
<div class="inner-row">
<p class="bar-title">inflation</p>
<div class="bar">
<div class="fill fill_inverse"></div>
</div>
</div>
<div class="inner-row">
<p class="bar-title">growth</p>
<div class="bar">
<div class="fill fill_inverse"></div>
</div>
</div>
</div>
</div>
</main>
<footer>
<p><small>note: just meant to convey relationships, not scale or proportion.</small></p>
</footer>
html {
box-sizing: border-box;
}
*, *::before, *::after {
box-sizing: inherit;
&:focus {
outline: none;
}
}
* {
font-family: monaco, courier;
}
body {
margin: 0;
padding: 0;
}
h1 {
font-size: 1.25rem;
margin-bottom: 1rem;
color: darkslategray;
}
p {
margin: 0;
color: darkslategray;
}
.bar-title {
padding: 1.25rem 0 0.375rem 0;
}
.wrapper {
width: 100%;
min-height: 90vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background: Gainsboro;
}
.top-row {
width: 100%;
margin: 0.5rem auto;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.outer-row {
width: 100%;
margin-bottom: 2rem;
display: flex;
justify-content: center;
align-items: flex-start;
@media (max-width: 768px) {
flex-direction: column;
align-items: center;
}
}
.col, .inner-row {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.col {
width: 40%;
@media (max-width: 1000px) {
width: 100%;
}
}
.inner-row {
width: 100%;
}
footer {
min-height: 10vh;
margin: 0;
padding: 1rem 0;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background: Silver;
@media (max-width: 768px) {
p {
max-width: 80%;
}
}
}
// slider
.slider {
position: relative;
display: flex;
flex-direction: column;
width: 50vw;
height: 3rem;
margin: 0 auto;
@media (max-width: 768px) {
width: 80vw;
}
}
// number indicator below slider
.slider-output {
position: absolute;
left: 50%;
bottom: 0;
display: block;
box-sizing: border-box;
transform: translateX(-50%);
color: LightSlateGray;
}
.slider-track {
height: .5rem;
background-color: Silver;
border-radius: .25rem;
}
// slider circle handle
.slider-thumb {
position: absolute;
top: -.75rem;
left: 50%;
width: 2rem;
height: 2rem;
margin-left: -1rem;
border-radius: 1rem;
background-color: DarkMagenta;
}
// dark gray part of slider
.slider-level {
width: 50%;
height: .5rem;
background-color: LightSlateGray;
border-radius: 1rem;
}
// actual slider
.slider-input {
appearance: none;
position: absolute;
width: 105%; // specific width is required for Firefox
height: 2rem;
margin-left: -2.5%;
background-color: transparent;
outline: none;
}
.slider-input::slider-thumb {
width: 2rem;
height: 8rem;
appearance: none;
}
// https://css-tricks.com/styling-cross-browser-compatible-range-inputs-css/
// https://brennaobrien.com/blog/2014/05/style-input-type-range-in-every-browser.html
// removes the blue border but should add focus styling for accessibility
input[type=range]:focus {
outline: none;
}
// removes the dotted border in Firefox
input[type=range]::focus-outer {
border: 0;
}
// Firefox
input[type=range]::range-thumb {
background-color: transparent;
opacity: 0;
visibility: hidden;
background: transparent;
background-color: transparent;
border-color: transparent;
color: transparent;
}
// IE
input[type=range]::track {
width: 100%;
background: transparent;
background-color: transparent;
border-color: transparent;
color: transparent;
}
// bars
.bar {
width: 80%;
height: 10px;
border: 2px solid DarkMagenta;
}
.fill {
width: 50%;
height: 100%;
background: DarkMagenta;
}
View Compiled
"use strict";
function Slider(slider) {
this.slider = slider;
slider.addEventListener('input', function() {
this.updateSliderOutput();
this.updateSliderLevel();
this.updateBars();
}.bind(this), false);
this.level = function() {
// actual slider
let level = this.slider.querySelector('.slider-input');
return level.value;
}
this.levelString = function() {
return parseInt(this.level());
}
this.updateSliderOutput = function() {
// number indicator below slider
let output = this.slider.querySelector('.slider-output');
// slider circle handle
let thumb = this.slider.querySelector('.slider-thumb');
output.value = this.levelString();
output.style.left = this.levelString() + '%';
thumb.style.left = this.levelString() + '%';
}
this.updateSliderLevel = function() {
// dark gray part of slider
let level = this.slider.querySelector('.slider-level');
level.style.width = this.levelString() + '%';
}
this.updateBars = function() {
// actual slider
let level = this.slider.querySelector('.slider-input');
let analogousLevel = level.value;
let inverseLevel = 100 - level.value;
$('.fill_analogous').css('width', analogousLevel + '%');
$('.fill_inverse').css('width', inverseLevel + '%');
}
}
let volumeSlider = document.getElementById('volume');
new Slider(volumeSlider);
This Pen doesn't use any external CSS resources.