// This JavaScript has no part to play in the resizing of elements,
// but merely logs the size of each of the two columns in the
// relevant elements (the last <label> and the last <input>:
const D = document,
logLengths = () => {
let label = D.querySelector('label:last-of-type'),
input = D.querySelector('input:last-of-type');
[label, input].forEach(
(el) =>{
el[
el.tagName.toLowerCase() === 'input' ? 'value' : 'textContent'
] = Math.round(el.getBoundingClientRect().width*10)/10 + 'px';
});
};
logLengths();
D.querySelectorAll('label').forEach(
(label) => label.addEventListener('input', logLengths)
);
/* Generic CSS reset: */
*,
::before,
::after {
box-sizing: border-box;
font-size: 16px;
line-height: 1.5;
margin: 0;
padding: 0;
}
form {
border: 1px solid currentColor;
/* using CSS logical properties to place a 1em margin
on the block axis (top/bottom) in left-to-right, top-
to-bottom languages) */
margin-block: 1em;
/* ...and a margin of auto (to centre the element) on
the inline-axis (left and right in ltr languages): */
margin-inline: auto;
padding: 0.2em;
width: 90vw;
}
fieldset {
/* in order to use CSS Grid: */
display: grid;
/* setting gaps/'gutters' between rows of 0.5em,
and 0.25em gaps between adjacent columns: */
gap: 0.5em 0.25em;
/* defining two columns, the first of which is sized
'auto', allowing the layout to be sized appropriately
to the content within the limits of other columns,
the second column is sized using the 'minmax()'
function between a minimum size of 50% (because the
maximum permitted size of the first column is 50%),
and 1fr, which is the fractional unit of the remaining
space available: */
grid-template-columns: auto minmax(50%, 1fr);
}
/* this styles the 'information' <div> that provides
guidance about the interactivity of the editable
<label> elements: */
fieldset div {
grid-column: 1 / -1;
text-align: center;
padding: 0 2rem;
}
code, kbd {
font-family: consolas, ubuntu mono, monospace;
}
kbd {
border: 1px solid #aaa;
border-radius: 0.4em;
padding: 0.1em 0.3em;
}
label {
/* to indicate interactivity: */
cursor: pointer;
/* for positioning the pseudo element: */
position: relative;
}
/* entirely irrelevant to the demo, but just to
make it look a little prettier (adjust to
taste or remove as you like): */
label::before {
content: '';
background: linear-gradient(90deg, lime, #ffff);
height: 100%;
position: absolute;
transform: scaleX(0);
transition: transform 0.3s ease-in-out;
transform-origin: 0 100%;
width: 100%;
z-index: -1;
}
label:hover::before {
transform: scaleX(1);
}
.length {
background: revert;
background-color: #fff;
border-color: transparent;
border-top: 1px solid currentColor;
cursor: not-allowed;
font-style: italic;
text-align: center;
}
<form action="#">
<fieldset>
<!-- this <div> is here simply to provide some guidance as to the
interactivity of the <label> elements for the purpose of this
demo; otherwise it can be removed entirely: -->
<div>Most labels are <code>contentEditable</code>, though they will focus the <input> element when clicked; <kbd>shift</kbd>+<kbd>tab</kbd> to focus the <label></div>
<!-- because we're using a grid (and the majority of browsers don't yet
support display: subgrid) to create the aligned columns, the <input>
elements are the following-siblings of the <label> elements; in order
to associate the <label> with the correct <input> I've added an 'id'
attribute to each <input>, and the same id-value for the associated
<label> in their 'for' attribute; this means clicking/tapping on a
<label> will focus the appropriate <input>: -->
<label for="inputElement_0" contentEditable>longer label</label>
<input id="inputElement_0">
<label for="inputElement_1" contentEditable>label</label>
<input id="inputElement_1">
<label for="inputElement_2" contentEditable>medium label</label>
<input id="inputElement_2">
<label for="inputElement_3" contentEditable>label</label>
<input id="inputElement_3">
<label for="inputElement_4" contentEditable>label</label>
<input id="inputElement_4">
<label for="inputElement_5" contentEditable>label</label>
<input id="inputElement_5">
<!-- these elements are here purely to report the length of the
grid-columns in which they appear: -->
<label for="lengthInput" class="length"></label>
<input id="lengthInput" type="text" class="length" readonly>
</fieldset>
</form>