I have a css grid applied to a form layout, with dynamic number of elements per column, with code in React, for start i have first scenario (picture bellow), before tweaks i added to improve it a bit but still not working as expected:
As you can see here, one of the problems is causing text area which has height bigger than it is for text input which cause that whole row gets expanded which is also unexpected, corresponding html/css code for this is:
<fieldset
class="form-section"
style="display:grid; grid-gap: 1rem; grid-template-columns: repeat(3, min-content 1fr);
align-items: start"
>
<div style="grid-area: 1 / 1 / auto / span 1; place-self: center left">
<label
for="Email-e4400000754e818c2bb0408a8dce"
class="CaspioFormField-module_form-field-label-H5HRq"
><span class="">Email</span><span class=""> *</span></label
>
</div>
<div style="grid-area: 1 / 2 / auto / span 1">
<input
type="text"
id="Email-e4400000754e818c2bb0408a8dce"
class="p-inputtext p-component"
maxlength="255"
data-testid="input-text"
value=""
style="width: 300px"
/>
</div>
<div
style="
grid-area: 1 / 3 / auto / span 1;
justify-self: left;
padding-top: 1rem;
"
>
<label
for="Last_Name-e4400000754e818c2bb0408a8dce"
class="CaspioFormField-module_form-field-label-H5HRq"
><span class="">Last Name</span></label
>
</div>
<div style="grid-area: 1 / 4 / auto / span 1">
<textarea
id="Last_Name-e4400000754e818c2bb0408a8dce"
rows="5"
cols="50"
class="p-inputtextarea p-inputtext p-component"
></textarea>
</div>
<div style="grid-area: 1 / 5 / auto / span 1; place-self: center left">
<label
for="fieldInt-e4400000754e818c2bb0408a8dce"
class="CaspioFormField-module_form-field-label-H5HRq"
><span class="">fieldInt</span><span class=""> *</span></label
>
</div>
<div style="grid-area: 1 / 6 / auto / span 1">
<input
type="text"
id="fieldInt-e4400000754e818c2bb0408a8dce"
class="p-inputtext p-component"
maxlength="10"
data-testid="input-text"
value=""
/>
</div>
<div style="grid-area: 2 / 1 / auto / span 1; place-self: center left">
<label
for="Phone-e4400000754e818c2bb0408a8dce"
class="CaspioFormField-module_form-field-label-H5HRq"
><span class="">Phone</span><span class=""> *</span></label
>
</div>
<div style="grid-area: 2 / 2 / auto / span 1">
<input
type="text"
id="Phone-e4400000754e818c2bb0408a8dce"
class="p-inputtext p-component"
maxlength="15"
data-testid="input-text"
value=""
/>
</div>
<div style="grid-area: 2 / 3 / auto / span 1; place-self: center left">
<label
for="List_Numbers-e4400000754e818c2bb0408a8dce"
class="CaspioFormField-module_form-field-label-H5HRq"
><span class="">List Numbers</span></label
>
</div>
<div style="grid-area: 2 / 4 / auto / span 1">
<div
id="List_Numbers-e4400000754e818c2bb0408a8dce-component"
class="p-multiselect p-component p-inputwrapper"
style="width: 236px"
>
<div class="p-hidden-accessible">
<input
id="List_Numbers-e4400000754e818c2bb0408a8dce"
readonly=""
type="text"
role="listbox"
aria-expanded="false"
tabindex="0"
/>
</div>
<div class="p-multiselect-label-container">
<div class="p-multiselect-label p-multiselect-label-empty">empty</div>
</div>
<div class="p-multiselect-trigger">
<svg
width="14"
height="14"
viewBox="0 0 14 14"
fill="none"
xmlns="http://www.w3.org/2000/svg"
class="p-icon p-multiselect-trigger-icon p-c"
aria-hidden="true"
>
<path
d="M7.01744 10.398C6.91269 10.3985 6.8089 10.378 6.71215 10.3379C6.61541 10.2977 6.52766 10.2386 6.45405 10.1641L1.13907 4.84913C1.03306 4.69404 0.985221 4.5065 1.00399 4.31958C1.02276 4.13266 1.10693 3.95838 1.24166 3.82747C1.37639 3.69655 1.55301 3.61742 1.74039 3.60402C1.92777 3.59062 2.11386 3.64382 2.26584 3.75424L7.01744 8.47394L11.769 3.75424C11.9189 3.65709 12.097 3.61306 12.2748 3.62921C12.4527 3.64535 12.6199 3.72073 12.7498 3.84328C12.8797 3.96582 12.9647 4.12842 12.9912 4.30502C13.0177 4.48162 12.9841 4.662 12.8958 4.81724L7.58083 10.1322C7.50996 10.2125 7.42344 10.2775 7.32656 10.3232C7.22968 10.3689 7.12449 10.3944 7.01744 10.398Z"
fill="currentColor"
></path>
</svg>
</div>
</div>
</div>
<div style="grid-area: 2 / 5 / auto / span 1; place-self: center left">
<label
for="dateCreated-e4400000754e818c2bb0408a8dce"
class="CaspioFormField-module_form-field-label-H5HRq"
><span class="">dateCreated</span></label
>
</div>
<div style="grid-area: 2 / 6 / auto / span 1">
<span
class="p-calendar p-component p-inputwrapper p-calendar-w-btn p-calendar-w-btn-right"
><input
id="dateCreated-e4400000754e818c2bb0408a8dce"
type="text"
class="p-inputtext p-component"
autocomplete="off"
inputmode="none"
/><button
type="button"
tabindex="-1"
class="p-button p-component p-datepicker-trigger p-button-icon-only"
>
<span class="pi pi-calendar"></span
><span class="p-button-label p-c"> </span>
</button></span
>
</div>
<div style="grid-area: 3 / 1 / auto / span 1; place-self: center left">
<label
for="text64-e4400000754e818c2bb0408a8dce"
class="CaspioFormField-module_form-field-label-H5HRq"
><span class="">text64</span></label
>
</div>
<div style="grid-area: 3 / 2 / auto / span 1">
<input
type="password"
id="text64-e4400000754e818c2bb0408a8dce"
class="p-inputtext p-component"
maxlength="64000"
data-testid="input-text"
value=""
/>
</div>
<div style="grid-area: 3 / 3 / auto / span 1; place-self: center left">
<label
for="First_Name-e4400000754e818c2bb0408a8dce"
class="CaspioFormField-module_form-field-label-H5HRq"
><span class="">First Name</span></label
>
</div>
<div style="grid-area: 3 / 4 / auto / span 1">
<input
type="text"
id="First_Name-e4400000754e818c2bb0408a8dce"
class="p-inputtext p-component"
maxlength="255"
data-testid="input-text"
value=""
/>
</div>
</fieldset>
what i did here to improve this is that i set grid-row-end for multiline form elements, in this case it is textarea element to span 2, and to all elements which are bellow this element to grid-row: auto and this looks like this:
<fieldset
class="form-section"
style="grid-template-columns: repeat(3, min-content 1fr); align-items: start"
>
<div style="grid-area: 1 / 1 / auto / span 1; place-self: center left">
<label
for="Email-e4400000754e818c2bb0408a8dce"
class="CaspioFormField-module_form-field-label-H5HRq"
><span class="">Email</span><span class=""> *</span></label
>
</div>
<div style="grid-area: 1 / 2 / auto / span 1">
<input
type="text"
id="Email-e4400000754e818c2bb0408a8dce"
class="p-inputtext p-component"
maxlength="255"
data-testid="input-text"
value=""
style="width: 300px"
/>
</div>
<div
style="
grid-area: 1 / 3 / span 2 / span 1;
justify-self: left;
padding-top: 1rem;
"
>
<label
for="Last_Name-e4400000754e818c2bb0408a8dce"
class="CaspioFormField-module_form-field-label-H5HRq"
><span class="">Last Name</span></label
>
</div>
<div style="grid-area: 1 / 4 / span 2 / span 1">
<textarea
id="Last_Name-e4400000754e818c2bb0408a8dce"
rows="5"
cols="50"
class="p-inputtextarea p-inputtext p-component"
></textarea>
</div>
<div style="grid-area: 1 / 5 / auto / span 1; place-self: center left">
<label
for="fieldInt-e4400000754e818c2bb0408a8dce"
class="CaspioFormField-module_form-field-label-H5HRq"
><span class="">fieldInt</span><span class=""> *</span></label
>
</div>
<div style="grid-area: 1 / 6 / auto / span 1">
<input
type="text"
id="fieldInt-e4400000754e818c2bb0408a8dce"
class="p-inputtext p-component"
maxlength="10"
data-testid="input-text"
value=""
/>
</div>
<div style="grid-area: 2 / 1 / auto / span 1; place-self: center left">
<label
for="Phone-e4400000754e818c2bb0408a8dce"
class="CaspioFormField-module_form-field-label-H5HRq"
><span class="">Phone</span><span class=""> *</span></label
>
</div>
<div style="grid-area: 2 / 2 / auto / span 1">
<input
type="text"
id="Phone-e4400000754e818c2bb0408a8dce"
class="p-inputtext p-component"
maxlength="15"
data-testid="input-text"
value=""
/>
</div>
<div style="grid-area: auto / 3 / auto / span 1; place-self: center left">
<label
for="List_Numbers-e4400000754e818c2bb0408a8dce"
class="CaspioFormField-module_form-field-label-H5HRq"
><span class="">List Numbers</span></label
>
</div>
<div style="grid-area: auto / 4 / auto / span 1">
<div
id="List_Numbers-e4400000754e818c2bb0408a8dce-component"
class="p-multiselect p-component p-inputwrapper"
style="width: 236px"
>
<div class="p-hidden-accessible">
<input
id="List_Numbers-e4400000754e818c2bb0408a8dce"
readonly=""
type="text"
role="listbox"
aria-expanded="false"
tabindex="0"
/>
</div>
<div class="p-multiselect-label-container">
<div class="p-multiselect-label p-multiselect-label-empty">empty</div>
</div>
<div class="p-multiselect-trigger">
<svg
width="14"
height="14"
viewBox="0 0 14 14"
fill="none"
xmlns="http://www.w3.org/2000/svg"
class="p-icon p-multiselect-trigger-icon p-c"
aria-hidden="true"
>
<path
d="M7.01744 10.398C6.91269 10.3985 6.8089 10.378 6.71215 10.3379C6.61541 10.2977 6.52766 10.2386 6.45405 10.1641L1.13907 4.84913C1.03306 4.69404 0.985221 4.5065 1.00399 4.31958C1.02276 4.13266 1.10693 3.95838 1.24166 3.82747C1.37639 3.69655 1.55301 3.61742 1.74039 3.60402C1.92777 3.59062 2.11386 3.64382 2.26584 3.75424L7.01744 8.47394L11.769 3.75424C11.9189 3.65709 12.097 3.61306 12.2748 3.62921C12.4527 3.64535 12.6199 3.72073 12.7498 3.84328C12.8797 3.96582 12.9647 4.12842 12.9912 4.30502C13.0177 4.48162 12.9841 4.662 12.8958 4.81724L7.58083 10.1322C7.50996 10.2125 7.42344 10.2775 7.32656 10.3232C7.22968 10.3689 7.12449 10.3944 7.01744 10.398Z"
fill="currentColor"
></path>
</svg>
</div>
</div>
</div>
<div style="grid-area: 2 / 5 / auto / span 1; place-self: center left">
<label
for="dateCreated-e4400000754e818c2bb0408a8dce"
class="CaspioFormField-module_form-field-label-H5HRq"
><span class="">dateCreated</span></label
>
</div>
<div style="grid-area: 2 / 6 / auto / span 1">
<span
class="p-calendar p-component p-inputwrapper p-calendar-w-btn p-calendar-w-btn-right"
><input
id="dateCreated-e4400000754e818c2bb0408a8dce"
type="text"
class="p-inputtext p-component"
autocomplete="off"
inputmode="none"
/><button
type="button"
tabindex="-1"
class="p-button p-component p-datepicker-trigger p-button-icon-only"
>
<span class="pi pi-calendar"></span
><span class="p-button-label p-c"> </span>
</button></span
>
</div>
<div style="grid-area: 3 / 1 / auto / span 1; place-self: center left">
<label
for="text64-e4400000754e818c2bb0408a8dce"
class="CaspioFormField-module_form-field-label-H5HRq"
><span class="">text64</span></label
>
</div>
<div style="grid-area: 3 / 2 / auto / span 1">
<input
type="password"
id="text64-e4400000754e818c2bb0408a8dce"
class="p-inputtext p-component"
maxlength="64000"
data-testid="input-text"
value=""
/>
</div>
<div style="grid-area: 3 / 3 / auto / span 1; place-self: center left">
<label
for="First_Name-e4400000754e818c2bb0408a8dce"
class="CaspioFormField-module_form-field-label-H5HRq"
><span class="">First Name</span></label
>
</div>
<div style="grid-area: 3 / 4 / auto / span 1">
<input
type="text"
id="First_Name-e4400000754e818c2bb0408a8dce"
class="p-inputtext p-component"
maxlength="255"
data-testid="input-text"
value=""
/>
</div>
</fieldset>
and this looks better:
but as now i added that textarea spans only two rows, if i tend to get something like this:
the space between these two inputs is bigger as they tend to fill the corresponding height of the text area, and if for example i add bigger height of text area i get bigger gap:
and if i try to dynamically change this span to 3 instead of two than this is what i get:
Bottom line is, what i am trying to achieve here is to have row area which is not expanding for each column but only where it is needed as it is for text area, the height of normal text-input is 45px and the height of textarea can vary per rows like 45px, 64px, 83px, 102px, 125px..., Can i somehow dinamically set this spaning based on textarea height, or what can i do to achieve independent columns here? Also there is bunch of other cases with elements like checkbox with even less height which tend to break here because of this.
I would implement this with nested grids. The outer grid manages the three columns, but has a single row, so a total of three cells. Each cell in this grid then contains a nested grid to manage its own labels and entry fields.
body {
margin: 1em;
background: #f6f6f6;
}
fieldset {
display: grid;
gap: 2em;
grid-template-columns: repeat(3, minmax(0, 1fr));
border: 0;
padding: 0;
}
.column {
display: grid;
gap: 1em;
grid-template-columns: 2fr 5fr;
align-content: start;
}
input, select, textarea {
max-width: 100%;
border: 1px solid #bbb;
border-radius: 4px;
box-shadow: 0 0 5px rgb(0 0 0 / 0.1);
}
select {
appearance: none;
}
<fieldset>
<div class="column">
<label>Email *</label>
<input type="email"/>
<label>Phone *</label>
<input type="text"/>
<label>text64</label>
<input type="text"/>
</div>
<div class="column">
<label>List Numbers</label>
<select></select>
<label>Last Name</label>
<textarea rows="5"></textarea>
<label>First Name</label>
<input type="text"/>
</div>
<div class="column">
<label>fieldInt *</label>
<input type="text"/>
<label>dateCreated</label>
<input type="text"/>
<label>List Strings</label>
<select></select>
<label>isSubscribed</label>
<input type="checkbox">
<label>somelistdate</label>
<select></select>
</div>
</fieldset>