Reputation: 29
I have a form with the bottom-aligned behaviour, I need all the inputs in a row to be aligned to the bottom and be on one line visually. The reason for this is that the label can include instructions or not include them. The controls can be of different hight and type (text input, select, radio group, checkbox group, fieldset). The form that is used is antd Form component that is build using flex, that's why the markup of input's and label's wrappers cannot be changed. Also the each ant class have it's own styles:
I use the align-self: end;
to make the control div to be aligned to the bottom. It works fine when I have one-line error
But it doesn't look good when I have multi-line error.
Can anyone suggest how to align the controls properly using the CSS (maybe grid...)?
The desired result (the right input is located one the same line as the left one):
Thank you!
https://codepen.io/Ke1sy/pen/gOELweY
HTML:
<div class="container">
<div class="ant-form ant-form-vertical ant-form-align-fields-bottom">
<div class="ant-row">
<div class="ant-col ant-col-xs-24 ant-col-sm-12 ant-col-lg-8">
<div class="ant-form-item ant-form-item-with-help">
<div class="ant-row ant-form-item-row">
<div class="ant-col ant-form-item-label">
<div>Label </div>
<div style="color: grey">Long instructionsLong instructionsLong instructionsLong </div>
</div>
<div class="ant-col ant-form-item-control">
<div class="input"><input type="text"></div>
<div class="error">Long error Long error Long errorLong errorLong errorLong errorLong errorLong error</div>
</div>
</div>
</div>
</div>
<div class="ant-col ant-col-xs-24 ant-col-sm-12 ant-col-lg-8">
<div class="ant-form-item ant-form-item-with-help">
<div class="ant-row ant-form-item-row">
<div class="ant-col ant-form-item-label">Label</div>
<div class="ant-col ant-form-item-control control">
<div class="input"><input type="text"></div>
<div class="error">Short instructions</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
The styles that are applied over the antd styles:
body {
margin: 0;
}
.container {
max-width: 900px;
}
.error {
color: red;
padding: 5px 0;
}
.ant-form-item {
border: 5px solid rgb(111, 41, 97);
}
.ant-form-item-label {
background: orange;
width: 100%;
}
.ant-form-item-control {
background: #eee;
padding: 10px;
width: 100%;
}
.ant-form-align-fields-bottom {
.ant-form-item {
height: 100%;
.ant-form-item-row {
height: 100%;
display: grid;
.ant-form-item-control {
align-self: end;
}
}
}
}
Antd css file to include: https://cdnjs.cloudflare.com/ajax/libs/antd/4.24.15/antd.compact.min.css
Upvotes: 2
Views: 466
Reputation: 121
maybe try a tooltip for :hover
?
changes marked with comments. as always :3
body {
margin: 0;
}
.container {
max-width: 900px;
}
/* changes start */
.ant-form{
display:grid;
grid-template-columns: 1fr 1fr;
}
.ant-form-item-control{position: relative;}
.input{margin-bottom: 2.3em;}
.error {
color: red;
padding: 3px 0;
position: absolute;
bottom: 0;
height: 1.1em;
background: #eee;
overflow: hidden;
border: 3px double red;
border-radius: .5em .5em 0 0;
border-bottom: none;
}
.error:hover {
height: auto;
}
/* changes end */
.ant-form-item {
border: 5px solid #6f2961;
}
.ant-form-item-label {
background: orange;
width: 100%;
}
.ant-form-item-control {
background: #eee;
padding: 10px;
width: 100%;
}
.ant-form-align-fields-bottom .ant-form-item {
height: 100%;
}
.ant-form-align-fields-bottom .ant-form-item .ant-form-item-row {
height: 100%;
display: grid;
}
.ant-form-align-fields-bottom .ant-form-item .ant-form-item-row .ant-form-item-control {
align-self: end;
}
<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/antd/4.24.15/antd.compact.min.css'>
<div class="container">
<div class="ant-form ant-form-vertical ant-form-align-fields-bottom">
<div class="ant-row">
<div class="ant-col ant-col-xs-24 ant-col-sm-12 ant-col-lg-8">
<div class="ant-form-item ant-form-item-with-help">
<div class="ant-row ant-form-item-row">
<div class="ant-col ant-form-item-label">
<div>Label </div>
<div style="color: grey">Long instructionsLong instructionsLong instructionsLong </div>
</div>
<div class="ant-col ant-form-item-control">
<div class="input"><input type="text"></div>
<div class="error">Long error Long error Long errorLong errorLong errorLong errorLong errorLong error</div>
</div>
</div>
</div>
</div>
<div class="ant-col ant-col-xs-24 ant-col-sm-12 ant-col-lg-8">
<div class="ant-form-item ant-form-item-with-help">
<div class="ant-row ant-form-item-row">
<div class="ant-col ant-form-item-label">Label</div>
<div class="ant-col ant-form-item-control control">
<div class="input"><input type="text"></div>
<div class="error">Short instructions</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Upvotes: 0
Reputation: 9815
Based on your html, you can apply .form-item { grid-template-rows:subgrid; }
. Here is a simple example:
body {
margin: 0;
}
.form {
display: grid;
grid-template-columns: repeat(auto-fit, 300px);
}
.error {
color: red;
padding: 5px 0
}
.form-item {
border: 5px solid rgb(111, 41, 97);
display: grid;
grid-template-rows: subgrid;
grid-row: span 2;
}
.label {
background: orange;
}
.control {
background: #eee;
padding: 10px;
}
<form class="form">
<div class="form-item">
<div class="label">
<div>Label </div>
<div style="color: grey">Long instructionsLong instructionsLong instructionsLong instructions Long instructions Long instructionsLong instructionsLong instructionsLong instructions Long instruction </div>
</div>
<div class="control">
<div class="input"><input type="text"></div>
<div class="error">Long error Long error Long errorLong errorLong </div>
</div>
</div>
<div class="form-item">
<div class="label">Label</div>
<div class="control">
<div class="input"><input type="text"></div>
<div class="error">Short error</div>
</div>
</div>
<div class="form-item">
<div class="label">Label</div>
<div class="control">
<div class="input"><input type="text"></div>
<div class="error">errorLong errorLong errorLong errorLong error Long error Long errorLong errorLong errorLong errorLong errorLong er</div>
</div>
</div>
</form>
Using your provided html code:
body {
padding: 50px;
font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}
.ant-form>.ant-row{
display: grid;
grid-template-columns:1fr 1fr;
}
.error {
color: red;
padding: 5px 0
}
.ant-form>.ant-row>.ant-col{
border: 5px solid rgb(111, 41, 97);
display: grid;
grid-template-rows:subgrid;
grid-row:span 2;
width:auto;
max-width:unset;
}
.ant-form>.ant-row>.ant-col>.ant-form-item,
.ant-form>.ant-row>.ant-col>.ant-form-item>.ant-form-item-row{
display: grid;
grid-template-rows:subgrid;
grid-row:span 2;
}
.ant-form>.ant-row>.ant-col>.ant-form-item{
margin:0;
}
.ant-form>.ant-row .ant-form-item-label {
background: orange;
padding: 10px;
}
.control {
background: #eee;
padding: 10px;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/antd/4.24.15/antd.compact.min.css">
<div class="container">
<div class="ant-form ant-form-vertical ant-form-align-fields-bottom">
<div class="ant-row">
<div class="ant-col ant-col-xs-24 ant-col-sm-12 ant-col-lg-8">
<div class="ant-form-item ant-form-item-with-help">
<div class="ant-row ant-form-item-row">
<div class="ant-col ant-form-item-label">
<div>Label </div>
<div style="color: grey">Long instructionsLong instructionsLong instructionsLong </div>
</div>
<div class="ant-col ant-form-item-control control">
<div class="input"><input type="text"></div>
<div class="error">Long error Long error Long errorLong errorLong errorLong errorLong errorLong error</div>
</div>
</div>
</div>
</div>
<div class="ant-col ant-col-xs-24 ant-col-sm-12 ant-col-lg-8">
<div class="ant-form-item ant-form-item-with-help">
<div class="ant-row ant-form-item-row">
<div class="ant-col ant-form-item-label">Label</div>
<div class="ant-col ant-form-item-control control">
<div class="input"><input type="text"></div>
<div class="error">Short instructions</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
You don't mention in your question that you have no control over the grid markup. Just understand that there is either css grid or javascript. So if this form, let's say, comes with a backend, then you probably know exactly which columns are all defined. If you can set this in a variable for grid-template-columns
and add variable styles similar to the .ant-col
style.
And, yes, it will be a difficult decision, and maybe even a crazy one...
body {
padding: 50px;
font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}
.ant-form>.ant-row{
display: grid;
}
@media (min-width: 992px) {
.ant-form>.ant-row{
--lg-8:33%;
--lg-6:25%;
}
}
@media (min-width: 768px) {
.ant-form>.ant-row{
--md-8:33%;
--md-6:25%;
}
}
@media (min-width: 576px) {
.ant-form>.ant-row{
--sm-6:50%;
--sm-6:50%;
}
}
.error {
color: red;
padding: 5px 0
}
.ant-form>.ant-row>.ant-col{
border: 5px solid rgb(111, 41, 97);
display: grid;
grid-template-rows:subgrid;
grid-row:span 2;
width:auto;
max-width:unset;
}
.ant-form>.ant-row>.ant-col>.ant-form-item,
.ant-form>.ant-row>.ant-col>.ant-form-item>.ant-form-item-row{
display: grid;
grid-template-rows:subgrid;
grid-row:span 2;
}
.ant-form>.ant-row>.ant-col>.ant-form-item{
margin:0;
}
.ant-form>.ant-row .ant-form-item-label {
background: orange;
padding: 10px;
}
.control {
background: #eee;
padding: 10px;
min-width: 0;
}
.ant-form input{
max-width: 100%;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/antd/4.24.15/antd.compact.min.css">
<div class="container">
<div class="ant-form ant-form-vertical ant-form-align-fields-bottom">
<div class="ant-row" style="grid-template-columns:var(--lg-8, var(--md-8, var(--sm-6))) var(--lg-6, var(--md-6, var(--sm-6)));">
<div class="ant-col ant-col-lg-8 ant-col-md-8 ant-col-sm-6">
<div class="ant-form-item ant-form-item-with-help">
<div class="ant-row ant-form-item-row">
<div class="ant-col ant-form-item-label">
<div>Label </div>
<div style="color: grey">Long instructionsLong instructionsLong instructionsLong Long instructionsLong instructionsLong instructionsLong Long instructionsLong instructionsLong instructionsLong Long instructionsLong instructionsLong instructionsLong Long instructionsLong instructionsLong instructionsLong</div>
</div>
<div class="ant-col ant-form-item-control control">
<div class="input"><input type="text"></div>
<div class="error">Long error Long error Long errorLong errorLong errorLong errorLong errorLong error Long error Long error Long errorLong errorLong errorLong errorLong errorLong error Long error Long error Long errorLong errorLong errorLong errorLong errorLong error </div>
</div>
</div>
</div>
</div>
<div class="ant-col ant-col-lg-6 ant-col-md-6 ant-col-sm-6">
<div class="ant-form-item ant-form-item-with-help">
<div class="ant-row ant-form-item-row">
<div class="ant-col ant-form-item-label">Label</div>
<div class="ant-col ant-form-item-control control">
<div class="input"><input type="text"></div>
<div class="error">Short instructions</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Upvotes: 1
Reputation: 1846
body {
margin: 0;
}
.container {
max-width: 900px;
width: 500px;
}
.ant-row-tbl {
display: grid;
grid-template-columns: repeat(auto-fill, 1fr); /* Creates a flexible number of columns */
grid-template-rows: auto auto; /* Creates two rows, auto-sized */
column-gap: 6px; /* Vertical gap between columns */
row-gap: 0; /* no gap between rows */
}
/* Assuming .ant-col is a shared class for label and control */
.ant-col {
/* Styling for both label and control */
padding: 10px; /* Adjust padding as needed */
box-sizing: border-box; /* Padding included in the width */
}
.ant-form-item-label {
background: orange;
grid-row: 1; /* Place label in the first row */
}
.ant-form-item-control {
background: #eee;
grid-row: 2; /* Place control in the second row */
}
/* Assuming .ant-col is a shared class for label and control */
.ant-col {
/* Styling for both label and control */
padding: 10px;
/* Adjust padding as needed */
box-sizing: border-box;
/* Padding included in the width */
}
.ant-form-item-label {
background: orange;
grid-row: 1;
/* Place label in the first row */
}
.ant-form-item-control {
background: #eee;
grid-row: 2;
/* Place control in the second row */
}
<div class="container">
<div class="ant-form ant-form-vertical ant-form-align-fields-bottom">
<div class="ant-row-tbl">
<div class="ant-col ant-form-item-label">
<div>Label </div>
<div style="color: grey">Long instructionsLong instructionsLong<br /><br />instructionsLong </div>
</div>
<div class="ant-col ant-form-item-control">
<div class="input"><input type="text"></div>
<div class="error">Long error Long error Long errorLong errorLong errorLong errorLong errorLong error</div>
</div>
<div class="ant-col ant-form-item-label">
<div>Label</div>
</div>
<div class="ant-col ant-form-item-control">
<div class="input"><input type="text"></div>
<div class="error">Short instructions</div>
</div>
<div class="ant-col ant-form-item-label">
<div>Label3</div>
</div>
<div class="ant-col ant-form-item-control">
<div class="input"><input type="text"></div>
<div class="error">Short rrrr</div>
</div>
</div>
</div>
</div>
Upvotes: 0
Reputation: 321
you could use that site for grid helper: for more https://cssgrid-generator.netlify.app/
body {
padding: 50px;
font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}
.form {
display: grid;
grid-template-columns: repeat(2, 1fr);
/* for more https://cssgrid-generator.netlify.app/ */
grid-column-gap: 0px;
grid-row-gap: 0px;
}
@media only screen and (max-width: 600px) {
.form {
grid-template-columns: repeat(1, 1fr);
}
}
.error {
color: red;
padding: 5px 0
}
.form-item {
border: 5px solid rgb(111, 41, 97);
display: grid;
grid-template-columns: 1fr;
grid-template-rows: repeat(2, 1fr);
grid-column-gap: 0px;
grid-row-gap: 0px;
}
.label {
background: orange;
}
.control {
background: #eee;
padding: 10px;
}
<form class="form ">
<div class="form-item">
<div class="label">
<div>Label </div>
<div style="color: grey">Long instructionsLong instructionsLong instructionsLong instructions Long instructions Long instructionsLong instructionsLong instructionsLong instructions Long instruction </div>
</div>
<div class="control">
<div class="input"><input type="text"></div>
<div class="error">Long error Long error Long errorLong errorLong errorLong errorLong errorLong errorLong error Long error Long errorLong errorLong errorLong errorLong errorLong er</div>
</div>
</div>
<div class="form-item">
<div class="label">Label</div>
<div class="control">
<div class="input"><input type="text"></div>
<div class="error">Short error</div>
</div>
</div>
</form>
alternative solution are:
Upvotes: 0
Reputation: 459
Depending on the rest of your layout or other requirements you could use css-grid in order to get your desired layout.
If you remove the divs around each input and label, you could just use a grid, which flows in the column direction. The height of the rows will be defined by the largest item and therefore affect the other control-divs as well.
.form {
display: grid;
grid-template-rows: repeat(2, 1fr);
grid-auto-flow: column;
}
.error {
color: red;
padding: 5px 0;
}
.label {
background: orange;
}
.control {
background: #eee;
padding: 10px;
}
<form class="form">
<div class="label">
<div>Label</div>
<div style="color: grey">
Long instructionsLong instructionsLong instructionsLong instructions
Long instructions Long instructionsLong instructionsLong
instructionsLong instructions Long instruction sjhdjsdhdjshdsj
hsdjhsdssdhj jshdsjhjsh hjsdhdjsdhjshjdhjdshdjssdhjdhsjdshjsdd
jhjshdhjdsdhjsdhj
</div>
</div>
<div class="control">
<div class="input"><input type="text" /></div>
<div class="error">
Long error Long error Long errorLong errorLong errorLong errorLong
errorLong errorLong error Long error Long errorLong errorLong
jhsdhsjdhsjdh
</div>
</div>
<div class="label">Label</div>
<div class="control">
<div class="input"><input type="text" /></div>
<div class="error">Short error</div>
</div>
</form>
Upvotes: 0