<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||''));
})

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.