<div class="shell">
<div class="grid">
<div class="example">
<div class="example__heading">
Before
</div>
<div class="example__settings">
<div class="example__settingsField">
<div class="example__settingsValue"></div>
<div class="example__settingsControl">
<input class="js-inputRange js-fontSize" data-css-prop="--fontSize" data-css-unit="rem" id="js-fontSize01" min="0.75" max="4" step="0.25" type="range" value="1">
</div>
<div class="example__settingsLabel">
<label for="js-fontSize01">font-size</label>
</div>
</div>
<div class="example__settingsField">
<div class="example__settingsValue"></div>
<div class="example__settingsControl">
<input class="js-inputRange js-lineHeight" data-css-prop="--lineHeight" id="js-lineHeight01" min="1" max="3" step="0.1" type="range" value="1.5">
</div>
<div class="example__settingsLabel">
<label for="js-lineHeight01">line-height</label>
</div>
</div>
</div>
<div class="message message--before" style="--fontSize: 1rem; --lineHeight: 1.5">
<div class="message__icon">
<svg viewBox="0 0 16 16" class="message__svg">
<path fill="currentColor" d="M8 16A8 8 0 108 0a8 8 0 000 16zM7 4h2v2H7V4zm0 3h2v5H7V7z"></path>
</svg>
</div>
<div class="message__text">
Maecenas faucibus mollis interdum. Natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Integer posuere erat a ante venenatis dapibus posuere velit aliquet.
</div>
</div>
</div>
<div class="example">
<div class="example__heading">
After
</div>
<div class="example__settings">
<div class="example__settingsField">
<div class="example__settingsValue"></div>
<div class="example__settingsControl">
<input class="js-inputRange js-fontSize" data-css-prop="--fontSize" data-css-unit="rem" id="js-fontSize02" min="0.75" max="4" step="0.25" type="range" value="1">
</div>
<div class="example__settingsLabel">
<label for="js-fontSize02">font-size</label>
</div>
</div>
<div class="example__settingsField">
<div class="example__settingsValue"></div>
<div class="example__settingsControl">
<input class="js-inputRange js-lineHeight" data-css-prop="--lineHeight" id="js-lineHeight02" min="1" max="3" step="0.1" type="range" value="1.5">
</div>
<div class="example__settingsLabel">
<label for="js-lineHeight02">line-height</label>
</div>
</div>
</div>
<div class="message message--after" style="--fontSize: 1rem; --lineHeight: 1.5">
<div class="message__icon">
<svg viewBox="0 0 16 16" class="message__svg">
<path fill="currentColor" d="M8 16A8 8 0 108 0a8 8 0 000 16zM7 4h2v2H7V4zm0 3h2v5H7V7z"></path>
</svg>
</div>
<div class="message__text">
Maecenas faucibus mollis interdum. Natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Integer posuere erat a ante venenatis dapibus posuere velit aliquet.
</div>
</div>
</div>
</div>
</div>
.message {
$b: &;
--fontSize: 1rem;
--lineHeight: 1.5;
--iconSize: 1em;
--baselineDistance: calc(var(--fontSize) * var(--lineHeight));
--iconOffset: calc((var(--baselineDistance) - var(--fontSize)) * 0.5);
background-color: #cbeffb;
border-radius: 5px;
color: #1a2e3b;
font-size: var(--fontSize);
line-height: var(--lineHeight);
&__icon {
color: #00ADEF;
}
&--before {
padding: 1.25rem 2.5rem 1.25rem 2.875rem;
position: relative;
#{$b}__icon {
position: absolute;
left: 1.25rem;
}
#{$b}__svg {
display: inline-block;
height: 1rem;
vertical-align: middle;
width: 1rem;
}
}
&--after {
align-items: flex-start;
display: flex;
padding: 1.25rem 1.5rem;
#{$b}__icon {
align-items: flex-start;
display: flex;
flex-shrink: 0;
margin-right: 0.75em;
transform: translateY(var(--iconOffset));
width: var(--iconSize);
}
#{$b}__svg {
width: 100%;
}
#{$b}__text {
flex-grow: 1;
}
}
}
*,
*::before,
*::after {
box-sizing: border-box;
}
body {
color: #141414;
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji;
line-height: 1.5;
margin: 0;
}
.shell {
margin-left: auto;
margin-right: auto;
}
@media (min-width: 576px) {
.shell {
max-width: 85vw;
padding-left: 1rem;
padding-right: 1rem;
}
}
.grid {
align-items: start;
display: grid;
gap: 2rem;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
}
.example {
background-color: #f5f9f9;
padding: 1rem;
&__heading {
font-size: 2rem;
font-weight: bold;
}
&__settings {
background-color: #d8e3e7;
border: 1px solid #c0d2d8;
border-radius: 0.25rem;
margin-bottom: 1rem;
padding: 1rem;
}
&__settingsField {
align-items: center;
display: flex;
flex-direction: row-reverse;
justify-content: flex-end;
margin-bottom: 0.125rem;
}
&__settingsLabel {
flex-shrink: 0;
margin-right: 0.5rem;
text-align: right;
width: 80px;
}
&__settingsControl {
display: flex;
margin-right: 0.5rem;
}
&__settingsValue {
background-color: hotpink;
border-radius: 0.25rem;
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
font-size: 0.875rem;
padding: 0 0.25rem;
}
}
View Compiled
const examples = document.querySelectorAll('.example');
Array.from(examples).forEach((example) => {
const ranges = example.querySelectorAll('.js-inputRange');
const element = example.querySelector('.message');
Array.from(ranges).forEach((range) => {
range.addEventListener('input', () => {
element.style.setProperty(range.dataset.cssProp, `${range.value}${range.dataset.cssUnit ?? ''}`);
const output = range.parentElement.previousElementSibling;
output.textContent = `${range.value}${range.dataset.cssUnit ?? ''}`;
})
})
})