<ul class="ruler-x">
<li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li>
</ul>
<ul class="ruler-y">
<li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li>
</ul>
<form id="app" class="editor">
<fieldset>
<legend>Tall Ticks <em>Numbers align with this</em></legend>
<label>
<strong>Height</strong>
<input type="range" name="--ruler2-h" min="3" max="100" value="20" data-suffix="px">
</label>
<label>
<strong>Border-width</strong>
<input type="range" name="--ruler2-bdw" min="1" max="10" value="1" data-suffix="px">
</label>
<label>
<strong>Spacing</strong>
<input type="range" name="--ruler2-space" min="1" max="200" value="50">
</label>
<label>
<strong>Color</strong>
<input type="color" name="--ruler2-c" value="#BBBBBB">
</label>
</fieldset>
<fieldset>
<legend>Low Ticks</legend>
<label>
<strong>Height</strong>
<input type="range" name="--ruler1-h" min="3" max="100" value="8" data-suffix="px">
</label>
<label>
<strong>Border-width</strong>
<input type="range" name="--ruler1-bdw" min="1" max="10" value="1" data-suffix="px">
</label>
<label>
<strong>Spacing</strong>
<input type="range" name="--ruler1-space" min="1" max="100" value="5">
</label>
<label>
<strong>Color</strong>
<input type="color" name="--ruler1-c" value="#BBBBBB">
</label>
</fieldset>
<fieldset>
<legend>Other Options</legend>
<label>
<strong>Unit</strong>
<select name="--ruler-unit">
<option value="1mm">millimeter</option>
<option value="1in">inch</option>
<option value="1px" selected>pixel</option>
<option value="1em">em</option>
<option value="1ch">character</option>
<option value="1rem">rem</option>
<option value="1vw">viewport width</option>
<option value="1vh">viewport height</option>
</select>
</label>
<label>
<strong>Number Color</strong>
<input type="color" name="--ruler-num-c" value="#888">
</label>
<label>
<strong>Show x-axis</strong>
<input type="checkbox" name="--ruler-x" value="1" checked>
</label>
<label>
<strong>Show y-axis</strong>
<input type="checkbox" name="--ruler-y" value="1" checked>
</label>
</fieldset>
</form>
body {
--ruler-num-c: #888;
--ruler-num-fz: 10px;
--ruler-num-pi: 0.75ch;
--ruler-unit: 1px;
--ruler-x: 1;
--ruler-y: 1;
--ruler1-bdw: 1px;
--ruler1-c: #BBB;
--ruler1-h: 8px;
--ruler1-space: 5;
--ruler2-bdw: 1px;
--ruler2-c: #BBB;
--ruler2-h: 20px;
--ruler2-space: 50;
background-attachment: fixed;
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),
linear-gradient(0deg, var(--ruler1-c) 0 var(--ruler1-bdw), transparent 0),
linear-gradient(0deg, var(--ruler2-c) 0 var(--ruler2-bdw), transparent 0);
background-position: 0 0;
background-repeat: repeat-x, repeat-x, repeat-y, repeat-y;
background-size:
calc(var(--ruler-unit) * var(--ruler1-space) * var(--ruler-x)) var(--ruler1-h),
calc(var(--ruler-unit) * var(--ruler2-space) * var(--ruler-x)) var(--ruler2-h),
var(--ruler1-h) calc(var(--ruler-unit) * var(--ruler1-space) * var(--ruler-y)),
var(--ruler2-h) calc(var(--ruler-unit) * var(--ruler2-space) * var(--ruler-y));
}
/* Ruler Numbers */
.ruler-x,
.ruler-y {
color: var(--ruler-num-c);
counter-reset: d 0;
display: flex;
font-size: var(--ruler-num-fz);
line-height: 1;
list-style: none;
margin: 0;
overflow: hidden;
padding: 0;
position: fixed;
}
.ruler-x {
height: var(--ruler2-h);
inset-block-start: 0;
inset-inline-start: calc(var(--ruler-unit) * var(--ruler2-space));
opacity: var(--ruler-x);
width: 100%;
}
.ruler-y {
flex-direction: column;
height: 100%;
inset-block-start: calc(var(--ruler-unit) * var(--ruler2-space));
inset-inline-start: 0;
opacity: var(--ruler-y);
width: var(--ruler2-h);
}
.ruler-x li {
align-self: flex-end;
}
.ruler-x li,
.ruler-y li {
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);
}
.ruler-y li::after {
content: counter(d)"";
display: block;
padding-inline-end: var(--ruler-num-pi);
transform: rotate(-90deg) translateY(-13px);
transform-origin: 100% 0%;
text-align: end;
width: 100%;
}
/* DEMO, EDITOR */
* {
box-sizing: border-box;
}
body {
font-family: ui-sans-serif, system-ui, sans-serif;
min-height: 100vh;
margin: 0;
padding-block: calc(2rem + max(var(--ruler1-h), var(--ruler2-h)));
}
.editor {
display: flex;
flex-direction: column;
font-family: monospace;
gap: 1ch;
margin: 0 auto;
width: 18rem;
}
fieldset {
flex: 1;
padding: 1ch
}
input, select {
display: block;
}
label {
display: block;
margin-block-end: 2ch;
}
[dir="rtl"] .ruler {
background-position: 100% 0;
}
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||''));
})
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.