'Can't position HTML legend tag with CSS Grid
The Problem
I have a form with multiple fieldsets and a legend tag for accessibility reasons. I want the legend tag to be below the input field. Since I am using CSS Grid for the fieldset, the only way to get it working (on firefox) is to give the legend tag an absolute positioning.
In other browsers, such as Chrome and Edge this does not seem to render properly. What am I doing wrong? Why can't I seem to use CSS Grid to position a legend tag?
fieldset {
display: grid;
grid-template-columns: minmax(max-content, 12vw) auto;
grid-template-rows: auto auto;
position: relative;
padding-bottom: 2em;
}
fieldset legend {
position: absolute;
margin: 0;
padding: 0;
/**
* Suggested by user Kamel
* AFAIK legend is styled a block element by default.
* It definitely is for Firefox
*/
display: block;
grid-column: 2 / 3;
grid-row: 2 / 3;
}
<fieldset>
<legend>An accessible description</legend>
<label>Field</label>
<input type="text">
</fieldset>
<fieldset>
<legend>An accessible description</legend>
<label>Field</label>
<input type="text">
</fieldset>
Screenshot in Firefox (this is what I want to achieve)
My Research so far
MDN says:
The
<legend>
element is okay to style, but it can be a bit tricky to control placement of it. By default it is always positioned over the top border of its<fieldset>
parent, near the top left corner. To position it somewhere else, for example inside the fieldset somewhere, or near the bottom left corner, you need to rely on positioning.
https://developer.mozilla.org/en-US/docs/Learn/Forms/Styling_web_forms
But it doesn't seem to mention CSS Grid anywhere saying that it wouldn't work. Why shouldn't it? It works with all other elements too.
Solution 1:[1]
The problem is not with <legend>
but with <fieldset>
as grid which does not work in chrome.
Refer: Grid layout on <fieldset>... Bug on chrome?
So you need to add a grid wrapper
inside the <fieldset>
.
.grid-container {
display: grid;
grid-template-columns: minmax(max-content, 12vw) auto;
grid-template-rows: auto auto;
position: relative;
padding-bottom: 2em;
}
fieldset legend {
position: absolute;
margin: 0;
padding: 0;
/**
* Suggested by user Kamel
* AFAIK legend is styled a block element by default.
* It definitely is for Firefox
*/
/* display: block; */
grid-column: 2 / 3;
grid-row: 2 / 3;
}
<fieldset>
<div class="grid-container">
<legend>An accessible description</legend>
<label>Field</label>
<input type="text">
</div>
</fieldset>
<fieldset>
<div class="grid-container">
<legend>An accessible description</legend>
<label>Field</label>
<input type="text">
</div>
</fieldset>
Solution 2:[2]
?? As mentioned in comments under @Sree.Bh solution, wrapping everything inside the <fieldset>
with a div.grid-container
will break A11Y ?? since the <label>
is not a direct child anymore. This also produces a ? W3C error.
? My preferred solution is now W3C and A11Y acceptable
Wrapping the <fieldset>
with a div.grid-container
and then apply CSS display: contents;
to the <fieldset>
to inherit the grid-columns to all child elements of it like <legend>
and so on ?
Solution 3:[3]
The Tag use is only for fieldset caption.
The legened Display style must be block.
If you want to use a text below, must be in a label tag.
This is My Code working in both CHROME and FIREFOX
fieldset { display: grid; grid-template-columns: minmax(max-content, 12vw) auto; grid-template-rows: auto auto;
position: relative; padding-bottom: 2em; }
fieldset legend { position: block; margin: 0; padding: 0;
grid-column: 2 / 3; grid-row: 2 / 3; }
Field An accessible description
Field An accessible description
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Sree.Bh |
Solution 2 | |
Solution 3 | Kamel |