I'm currently working on a project, where an editor can easily edit breakpoints, using a group of color-coded, stacked <input type="range">
-controls, and a bit of JavaScript:
While this works, it's easier to visualize the breakpoints, if combined with a ruler:
At first, I hardcoded a ruler, using pixels — but then I thought: “What if the editor wants to define the breakpoints in em
or ch
— or some other unit?”
Let's look into how we can create a configurable ruler, using CSS backround-image
, a bunch of variables — and only a tiny bit of JavaScript for a visual editor.
Our ruler will have two sets of “ticks” — low and tall (we'll look into the numbers later):
Both sets of ticks have some initial Custom Properties:
.ruler {
/* Low ticks */
--ruler1-bdw: 1px;
--ruler1-c: #BBB;
--ruler1-h: 8px;
--ruler1-space: 5;
/* Tall ticks */
--ruler2-bdw: 1px;
--ruler2-c: #BBB;
--ruler2-h: 20px;
--ruler2-space: 50;
}
With these properties, we can create a dynamic background-image
:
.ruler {
background-image:
linear-gradient(90deg, var(--ruler1-c) 0 var(--ruler1-bdw), transparent 0),
linear-gradient(90deg, var(--ruler2-c) 0 var(--ruler2-bdw), transparent 0);
}
However, without background-repeat
and background-size
, we're not seeing anything that resembles a ruler!
.ruler {
background-repeat: repeat-x;
background-size:
calc(var(--ruler-unit) * var(--ruler1-space)) var(--ruler1-h),
calc(var(--ruler-unit) * var(--ruler2-space)) var(--ruler2-h);
}
And that's almost it! We just need to add background-attachment: fixed
, so the ruler will stay in place, when we're scrolling!
Adding numbers:
For the numbers, we'll create a list:
<ul class="ruler-x">
<li></li><li></li> <!-- repeat -->
</ul>
Each blank <li></li>
will be a number in our ruler. The number will be aligned to the bottom of the tall “ticks”:
.ruler-x {
color: var(--ruler-num-c);
counter-reset: d 0;
display: flex;
font-size: var(--ruler-num-fz);
height: var(--ruler2-h);
inset-block-start: 0;
inset-inline-start: calc(var(--ruler-unit) * var(--ruler2-space));
line-height: 1;
list-style: none;
margin: 0;
opacity: var(--ruler-x);
overflow: hidden;
padding: 0;
position: fixed;
width: 100%;
}
We'll use a CSS counter
to fill out the numbers, based on the --ruler2-space
-property:
.ruler-x li {
align-self: flex-end;
counter-increment: d var(--ruler2-space);
flex: 0 0 calc(var(--ruler-unit) * var(--ruler2-space));
}
.ruler-x li::after {
content: counter(d);
line-height: 1;
padding-inline-start: var(--ruler-num-pi);
}
Creating an Editor
Now, let's create a small editor for our ruler.
We'll use a small JavaScript to update the Custom Properties:
app.addEventListener('input', (e) => {
const input = e.target;
const value = input.type === 'checkbox' ? (input.checked ? 1 : 0) : input.value;
document.body.style.setProperty(input.name, value+(input.dataset.suffix||''));
})
In HTML, add <input>
s to <form id="app">
, using name
for the property to set, value
for the value (surprise!) and data-suffix
to add any suffix to the value:
<input type="range" name="--ruler1-h" value="8" data-suffix="px">
Repeat for all the properties, you want to be editable.
Demo
Here's a Codepen, where I've added a vertical ruler and an editor, using the technique described above (if you're on iOS, open it full-screen to avoid iframe scrolling-issues):
Bonus: right-to-left
If you want to use the y-axis
-ruler with rtl
, add a small snippet of CSS:
[dir="rtl"] .ruler {
background-position: 100% 0;
}
Cover-image from pexels.com
Top comments (5)
I also can share my experience! I recently discovered an amazing online ruler application that can be used on any device, including mobile phones, tablets, and computers. It is incredibly easy to use and is perfect for anyone. The best part is that it is completely free to use and offers a wide range of features, including customizable measurements and easy calibration. Whether you are a web developer or just need a quick and easy way to measure small objects, measure it with a virtual ruler!
I utterly love your implemention. Fantastic.
Thanks.
Thx!
Very cool, it's useful for my situation.
This is awesome, except I think the low-tick spacing option should be "divisions" between big-ticks because that is how rulers really are.