'How design a speedometer with HTML and CSS?
I am trying to design a speedometer as shown in the image:
I'm having a hard time making that design with CSS. So I need help from a CSS master. How can I place the numbers like that, just like the blue bars.
So far what I tried grab this:
#speedometer .wrapper {
width: 500px;
height: 250px;
border: 1px solid red;
border-top-left-radius: 360px;
border-top-right-radius: 360px;
overflow: hidden;
position: relative;
}
#speedometer .wrapper .indicator-wrapper {
position: absolute;
left: 10%;
top: 20%;
width: 80%;
height: 80%;
border-top-left-radius: 360px;
border-top-right-radius: 360px;
background-color: #ffffff;
z-index: 400;
}
#speedometer .wrapper .bar {
width: 100%;
height: 100%;
position: absolute;
transform-origin: bottom center;
}
#speedometer .wrapper .bar-1 {
top: 0;
left: 0;
z-index: 200;
transform: rotate(-140deg);
/* background-color: rgb(114, 114, 238); */
background-color: green;
}
#speedometer .wrapper .bar-2 {
top: 0;
right: 0;
z-index: 150;
transform: rotate(-90deg);
/* background-color: rgb(69, 69, 204); */
background-color: yellow;
}
#speedometer .wrapper .bar-3 {
top: 0;
left: 0;
z-index: 100;
transform: rotate(-40deg);
/* background-color: rgb(40, 40, 180); */
background-color: purple;
}
#speedometer .wrapper .bar-4 {
top: 0;
left: 0;
z-index: 0;
transform: rotate(30deg);
/* background-color: rgb(15, 15, 167); */
background-color: red;
}
<div id="speedometer">
<div class="wrapper">
<div class="indicator-wrapper">
<div class="indicator-wrapper-inner">
<div id="indicator"></div>
</div>
</div>
<div class="bar bar-1"></div>
<div class="bar bar-2"></div>
<div class="bar bar-3"></div>
<div class="bar bar-4"></div>
</div>
</div>
I need a lot of help to position the numbers like that, add the states: 'Good', 'Average', 'Bad', 'Very Bad' at the top. Likewise, add spacing between the bars. I know I'm asking a lot but the truth is costing me a lot. Thank you very much for your help
Solution 1:[1]
If you want to use just HTML and CSS you can put each number at the top of a long thin element which is then rotated about the bottom center of the speedometer.
There are 11 numbers so the number of degrees between each rotated element is 180/10;
Then each number is rotated back so it doesn't look rotated.
This snippet sets a CSS variable --num to the total number of numbers and uses CSS calc to calculate the rotations needed.
.speedometer {
--num: 11;
/* the total number of numbers */
width: 100vmin;
aspect-ratio: 2 / 1;
margin: 0;
padding: 0;
box-sizing: border-box;
position: relative;
}
.speedometer>* {
position: absolute;
bottom: 0;
left: calc(50% - 1em);
width: 2em;
height: 70%;
--deg: calc(180deg / calc(var(--num) - 1));
transform: rotate(calc(-90deg + calc((var(--n) - 1) * var(--deg))));
transform-origin: center bottom;
}
.speedometer>* * {
display: flex;
justify-content: center;
}
.speedometer>*>* {
transform: rotate(calc(90deg - ((var(--n) - 1) * var(--deg))));
}
.speedometer> :nth-child(1) {
--n: 1;
}
.speedometer> :nth-child(2) {
--n: 2;
}
.speedometer> :nth-child(3) {
--n: 3;
}
.speedometer> :nth-child(4) {
--n: 4;
}
.speedometer> :nth-child(5) {
--n: 5;
}
.speedometer> :nth-child(6) {
--n: 6;
}
.speedometer> :nth-child(7) {
--n: 7;
}
.speedometer> :nth-child(8) {
--n: 8;
}
.speedometer> :nth-child(9) {
--n: 9;
}
.speedometer> :nth-child(10) {
--n: 10;
}
.speedometer> :nth-child(11) {
display: inline-block;
--n: 11;
}
<div class="speedometer">
<div>
<div>0</div>
</div>
<div>
<div>10</div>
</div>
<div>
<div>20</div>
</div>
<div>
<div>30</div>
</div>
<div>
<div>40</div>
</div>
<div>
<div>50</div>
</div>
<div>
<div>60</div>
</div>
<div>
<div>70</div>
</div>
<div>
<div>80</div>
</div>
<div>
<div>90</div>
</div>
<div>
<div>100</div>
</div>
</div>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | A Haworth |
