I've looked everywhere but to no avail.
I got a <legend>
in a form, which displays as I want in every browsers, except in Chrome. It's like it sits outside of the fieldset, or it's like it goes on top of the next element. And it's very annoying. I can't even put margins on it.
Why does it display like in that way?
And is there a workaround?
HTML:
<fieldset class="col-12-box-bottom add-extras">
<legend class="plus">Add Promotion Code</legend>
<ul id="promo-fields">
<li><input class="field-small" type="text" /></li>
<li><button class="but-sec" type="submit">Apply</button></li>
</ul>
</fieldset>
CSS:
.add-extras legend{
width: 260px;
height: 0px;
border: 1px solid red;
display: block;
margin-top: 10px;
}
.add-extras fieldset{
position: relative;
}
.add-extras ul{
padding: 0 0 20px 0 !important;
overflow: hidden;
}
.add-extras li{
list-style-type: none;
float: left;
margin: 0 18px 0 0;
}
.add-extras li:last-child a{
color: #afafaf;
display: block;
margin: 27px 0px 0 0;
}
fieldset.add-extras{
margin: 0px 0 23px 0;
}
.add-extras label{
float: none;
display: block;
text-align: left;
width: 110px;
font-weight: bold;
margin: 0 0 5px 0;
}
This is a known issue with the legend
element in webkit browsers. There are no clean workarounds for the legend element itself, but you could instead add the margin to the first element that follows the legend.
Also, you'll have to explicitly set -webkit-margin-collapse: separate
on that element to make it work properly. Try using this:
legend + * {
-webkit-margin-top-collapse: separate;
margin-top: 10px;
}
http://jsfiddle.net/JLsPs/1/
(answer found here: Cannot add `margin` to `<legend>` element in Safari & Chrome (WebKit))
I have struggled with this issue many times, eventually leading to my abandoning the legend tag until recent, where I have begun using it again to add more semantic meaning to my markup.
Here is a fix I have devised to control the appearance of the legend tag's layout in relation to it's siblings:
Markup:
<div class="fieldset">
<fieldset>
<legend>Form Section</legend>
<div class="field_row">
<label for="first_name">First Name</label>
<input id="first_name" name="first_name" type="text">
</div>
<div class="field_row">
<label for="last_name">Last Name</label>
<input id="last_name" name="last_name" type="text">
</div>
</fieldset>
</div>
Styles:
.fieldset {
padding-top:48px; /*legend height(18px) + top value(15px) + bottom spacing(15px) */
position:relative;
}
legend {
height:18px; /* Default Height of non-styled legend element with default font-size of 16px as tested at time of this posting */
left:15px;
/*margin:15px 0;*/ /* Margins initially trying to achieve */
position:absolute;
top:15px; /* replaces top margin-top:15px; */
}
From the example I provided above, in order to achieve the bottom "margin" on the <legend> tag that you desire, you'll just apply a top padding to the fieldset equal to the amount of top and bottom margin you desire plus the explicit height of the legend tag. This pushes down the <legend>'s siblings down appropriately.
If you haven't explicitly set the height of your legend, you can just check it out in the metric tab of either Firebug or Chrome Developer tools, as the font-size will affect the height of it.
But yeah, pretty simple solution, I just ran into it again a few days ago when working on a client project. Then came across this question, as I was trying to do more research on it today.
Edit: I realized after posting this answer that in my original fix, I applied the padding to a parent <div> of the <fieldset> because for some reason Firefox starts the top:15px; from the bottom of the top padding, when the padding is applied to the <fieldset>. Putting the padding-top and position:relative; on the parent div allowed the <legend> to position absolutely over the padding instead of being pushed down by the padding. I have edited the code above to reflect my findings. This solution which started out simple, is less attractive to me now, but it definitely works. Here is a page that I created, testing two methods of positioning the <legend> tag: Legend tag positioning: http://dl.dropbox.com/u/37971131/css-testing/forms.html
The method proposed by Stephan Muller only works if the HTML element following the is visible. As in my case, this is not always possible without potentially large restructuring of the HTML code. Thus, in addition to his CSS code
legend + * {
-webkit-margin-top-collapse: separate;
margin-top: 10px;
}
just apply the following jQuery command, which basically just inserts an empty div (having a height of 0 px) but now matches the CSS selector adding the margin in every case:
$('legend + *').not(':visible').each(function() {
$('<div></div>').insertBefore($(this));
}
If updating the templates is not possible, you can use this script, just wrap the legend tag inside a div tag
jQuery('legend').each(function() {
jQuery(this).wrap( "<div></div>" );
});
Hope this helps! Enjoy coding..