问题
From my decades-long experience of hand-coding HTMLs, I have learnt that <form>
, <fieldset>
are just block
-level elements like <div>
. CSS-wise, they behave just the same in terms of positioning and sizing. (Please bear with me, I am ignoring old browsers like IE6 here. ) .... or so I thought....
*Before I go on, I have to state that I use Firefox for development and testing most of the time.
I was on a project with a lot of <form>
and <fieldset>
all over the place. To simplify my question here, I have something like:
<form>
<fieldset>
<div class="gridChild">...</div>
<div class="gridChild">...</div>
<div class="gridChild">...</div>
</fieldset>
</form>
I wanted to have the gridChild
div
s to be in layout of individual columns. So I had the CSS something like:
fieldset {
display: grid;
grid-template-columns: 50px 2fr 6fr 6fr auto ....;
}
And it worked. It showed the columns perfectly on my screen... It works on Firefox, Android and even Edge. The deadline was overdue. I was in rush and I didn't test it on Chrome. I thought that if Firefox and Edge works fine, then Chrome should work too, right? Or so I thought... Later on, I discovered that that doesn't work on Chrome. The grid layout is completely ignored on Chrome. I spent days just to debug the problem.
After a few sleepless nights, I found out that display:grid
doesn't work on <fieldset>
. It has to be applied to <div>
for Chrome to work. That was a surprise for me, because I have been doing so many CSS positioning, like floating, absolute-positioning, etc in a cross-browser fashion with <form>
and <fieldset>
, and they have been behaving just like <div>
all the time. But why not the Grid layout? Is this a bug for Chrome, or is this behaviour designed to be like that? Because I see that this is not a problem for Firefox, Edge and Android.
An easy fix I can think of is to wrap a <div>
inside <fieldset>
, like this:
<form>
<fieldset><div class="gridParent">
<div class="gridChild">...</div>
<div class="gridChild">...</div>
<div class="gridChild">...</div>
</div></fieldset>
</form>
But as I said before, I have <form>
and <fieldset>
all over the place. It would be best if I can avoid changing the HTML structures. I am writing here to seek for a CSS solution/hack, so I don't have to go through and rewrite hundreds of HTML lines.
回答1:
Another workaround for this issue is to use the form
as the grid object and use display: contents
on the fieldset
. This doesn't break semantic markup, though if there are multiple elements within the form they will all be included in the grid.
.some-form {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}
.some-form__fields {
display: contents;
}
<form class="some-form">
<fieldset class="some-form__fields">
<label>
First Name
<input type="text"/>
</label>
<label>
Last Name
<input type="text"/>
</label>
<label>
Favourite snack
<input type="text"/>
</label>
<label>
Favourite color
<input type="text"/>
</label>
</fieldset>
</form>
回答2:
Yeah this is a bug in Blink. fieldset has special cases rendering wise. https://bugs.chromium.org/p/chromium/issues/detail?id=262679
来源:https://stackoverflow.com/questions/51076747/grid-layout-on-fieldset-bug-on-chrome