<figure class="flex">
	<div class="group">
		<div class="group-icon">
			<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
				<path stroke-linecap="round" stroke-linejoin="round" d="M17.593 3.322c1.1.128 1.907 1.077 1.907 2.185V21L12 17.25 4.5 21V5.507c0-1.108.806-2.057 1.907-2.185a48.507 48.507 0 0 1 11.186 0Z" />
			</svg>
		</div>
		<div class="group-text">A single line of text.</div>
	</div>

	<div class="group">
		<div class="group-icon">
			<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
				<path stroke-linecap="round" stroke-linejoin="round" d="M17.593 3.322c1.1.128 1.907 1.077 1.907 2.185V21L12 17.25 4.5 21V5.507c0-1.108.806-2.057 1.907-2.185a48.507 48.507 0 0 1 11.186 0Z" />
			</svg>
		</div>
		<div class="group-text">
			<p>Professional cigarette 千葉市 black flatline lens military isotropic SAS dub.</p>
		</div>
	</div>
</figure>

<aside class="flex">
	<fieldset>
		<f-range id="fs" label="Font size" min="12" max="40" value="16"></f-range>
		<f-range id="lh" label="Line height" min="1" max="3" step="0.25" value="1.25"></f-range>
		<div class="f-field">
			<input type="checkbox" id="scale-icon" />
			<label for="scale-icon">Scale icon with font size</label>
		</div>
		<div class="f-callout" id="text-box-callout">
			<div class="f-field">
				<input type="checkbox" id="use-trim" />
				<label for="use-trim">Use <code>text-box-trim</code></label>
			</div>
		</div>
	</fieldset>
</aside>
@import url("https://rsms.me/inter/inter.css");

.group {
	display: flex;
	gap: 8px;
	align-items: flex-start;
	font-size: var(--font-size, 16px);
	line-height: var(--line-height, 1.25);
}

.group-icon {
	display: flex;
	align-items: center;
	justify-content: center;
	flex: none;
	block-size: 1lh;

	> svg {
		block-size: 24px;
		inline-size: 24px;
		flex-shrink: 0;
	}

	&.is-scaled > svg {
		block-size: 1.5em;
		inline-size: 1.5em;
	}

	&.is-trimmed {
		block-size: 1cap;
	}
}

.group-text {
	&.is-trimmed {
		text-box: cap alphabetic;
	}
}

@layer presentation {
	.flex {
		flex-direction: column;
		gap: var(--size-6);
	}

	.group-text > p {
		max-inline-size: var(--size-content-2);
		font-size: inherit;
	}

	f-range {
		inline-size: 80%;
	}

	.not-supported {
		flex-direction: column;
		align-items: flex-start;

		&::before {
			content: "This property is not supported in your browser.";
		}
	}
}
const fs = document.getElementById("fs");
const lh = document.getElementById("lh");
const scaleToggle = document.getElementById("scale-icon");
const trimToggle = document.getElementById("use-trim");

fs.addEventListener("f-range:input", (e) => {
	document.body.style.setProperty("--font-size", `${e.detail}px`);
});

lh.addEventListener("f-range:input", (e) => {
	document.body.style.setProperty("--line-height", `${e.detail}`);
});

scaleToggle.addEventListener("change", (e) => {
	let icons = document.getElementsByClassName("group-icon");
	Array.from(icons).forEach((el) => el.classList.toggle("is-scaled"));
});

if (!CSS.supports("text-box: cap")) {
	let container = document.getElementById("text-box-callout");

	container.classList.add("not-supported");
	trimToggle.setAttribute("disabled", true);
} else {
	trimToggle.addEventListener("change", (e) => {
		let icons = document.getElementsByClassName("group-icon");
		let text = document.getElementsByClassName("group-text");
		Array.from(icons).forEach((el) => el.classList.toggle("is-trimmed"));
		Array.from(text).forEach((el) => el.classList.toggle("is-trimmed"));
	});
}

External CSS

  1. https://codepen.io/stormwarning/pen/zGaRGQ.css

External JavaScript

  1. https://codepen.io/stormwarning/pen/zGaRGQ.js