Documented horizontal form-group fieldset markup is invalid HTML
Created by: tmorehouse
The <legend>
element must be the first child of the <fieldset>
element, which is not the case in the horizontal form-group layout using a fieldset:
- Docs: https://getbootstrap.com/docs/4.0/components/forms/#horizontal-form
- HTML5 validation: https://validator.w3.org/nu/?doc=https%3A%2F%2Fgetbootstrap.com%2Fdocs%2F4.0%2Fcomponents%2Fforms%2F
<fieldset class="form-group">
<div class="row">
<legend class="col-form-legend col-sm-2">Radios</legend>
<div class="col-sm-10">
<div class="form-check">
<label class="form-check-label">
<input class="form-check-input" type="radio" name="gridRadios" id="gridRadios1" value="option1" checked>
Option one is this and that—be sure to include why it's great
</label>
</div>
<div class="form-check">
<label class="form-check-label">
<input class="form-check-input" type="radio" name="gridRadios" id="gridRadios2" value="option2">
Option two can be something else and selecting it will deselect option one
</label>
</div>
</div>
</div>
</fieldset>
Visually, the above layout appears correct, but semantically it is incorrect (and not always announced correctly by screen readers, as they do not detect the <legend>
).
Changing the markup so that <legend>
is a direct first child of <fieldset>
(and moving class .row
to the fieldset) produces correctly validated HTML5, but the layout breaks:
<fieldset class="form-group row">
<legend class="col-form-legend col-sm-2">Radios</legend>
<div class="col-sm-10">
<div class="form-check">
<label class="form-check-label">
<input class="form-check-input" type="radio" name="gridRadios" id="gridRadios1" value="option1" checked>
Option one is this and that—be sure to include why it's great
</label>
</div>
<div class="form-check">
<label class="form-check-label">
<input class="form-check-input" type="radio" name="gridRadios" id="gridRadios2" value="option2">
Option two can be something else and selecting it will deselect option one
</label>
</div>
</div>
</fieldset>
Produces the following (the legend appears on a "line" by itself, even though its width is correct):
After playing with the classes/styles, the only way to get correct semantic markup and correct visual layout was to float the legend to the left:
<fieldset class="form-group row">
<legend class="float-left col-form-legend col-sm-2">Radios</legend>
<div class="col-sm-10">
<div class="form-check">
<label class="form-check-label">
<input class="form-check-input" type="radio" name="gridRadios" id="gridRadios1" value="option1" checked>
Option one is this and that—be sure to include why it's great
</label>
</div>
<div class="form-check">
<label class="form-check-label">
<input class="form-check-input" type="radio" name="gridRadios" id="gridRadios2" value="option2">
Option two can be something else and selecting it will deselect option one
</label>
</div>
</div>
</fieldset>
Browser used for testing: Firefox Codepen: https://codepen.io/tmorehouse/pen/BmMXKL
Maybe float: left;
should be added to the class .col-form-legend
(now known just as .col-form-label
) to allow valid HTML5 markup and visually correct layout?
Since the issue is only with the <label>
element, the following additional CSS could be used as an alternative:
fieldset > legend.col-form-label {
float: left;
}
Testing in mobile chrome, the "float" fix doesn't appear to work.
I am not sure if there is any alternative CSS trickery that could be used to correct this.
p.s. the div surrounding the radio inputs should have role="radiogroup"
(or role="group"
if checkboxes are used)