Some HTML elements come with preset designs, like the inconveniently small squares of <input type="checkbox">
elements, the limited-color bars of <meter>
elements, and the “something about them bothers me” arrows of the <details>
elements. We can style them to match the modern aesthetics of our websites while making use of their functionalities. There are also many elements that rarely get used as both their default appearance and functionality are less needed in modern web designs.
One such HTML element is <fieldset>
, along with its child element <legend>
.
A <fieldset>
element is traditionally used to group and access form controls. We can visually notice the grouping by the presence of a border around the grouped content on the screen. The caption for this group is given inside the <legend>
element that’s added as the first child of the <fieldset>
.
This combination of <fieldset>
and <legend>
creates a unique ready-made “text in border” design where the caption is placed right where the border is and the line of the border doesn’t go through the text. The border line “breaks” when it encounters the beginning of the caption text and resumes after the text ends.
In this post, we’ll make use of the <fieldset>
and <legend>
combo to create a more modern border text design that’s quick and easy to code and update.
For the four borders, we need four <fieldset>
elements, each containing a <legend>
element inside. We add the text that will appear at the borders inside the <legend>
elements.
<fieldset><legend>Wash Your Hands</legend></fieldset>
<fieldset><legend>Stay Apart</legend></fieldset>
<fieldset><legend>Wear A Mask</legend></fieldset>
<fieldset><legend>Stay Home</legend></fieldset>
To begin, we stack the <fieldset>
elements on top of each other in a grid cell and give them borders. You can stack them using any way you want — it doesn’t necessarily have to be a grid.
Only the top border of each <fieldset>
element is kept visible while the remaining edges are transparent since the text of the <legend>
element appears at the top border of the <fieldset>
by default.
Also, we give all the <fieldset>
elements a box-sizing
property with a value of border-box
so the width and height of the <fieldset>
elements include their border and padding sizes too. Doing this later creates a leveled design, when we style the <legend>
elements.
body {
display: grid;
margin: auto; /* to center */
margin-top: calc(50vh - 170px); /* to center */
width: 300px; height: 300px;
}
fieldset {
border: 10px solid transparent;
border-top-color: black;
box-sizing: border-box;
grid-area: 1 / 1; /* first row, first column */
padding: 20px;
width: inherit;
}
After this, we rotate the last three <fieldset>
elements in order to use their top borders as the side and bottom borders of our design.
/* rotate to right */
fieldset:nth-of-type(2){ transform: rotate(90deg); }
/* rotate to bottom */
fieldset:nth-of-type(3){ transform: rotate(180deg); }
/* rotate to left */
fieldset:nth-of-type(4){ transform: rotate(-90deg); }
Next up is styling the <legend>
elements. The key to create smooth border text using a <legend>
element is to give it a zero (or small enough) line-height
. If it has a large line height, that will displace the position of the border it’s in, pushing the border down. And when the border moves with the line height, we won’t be able to connect all the four sides of our design and will need to readjust the borders.
legend {
font: 15pt/0 'Averia Serif Libre';
margin: auto; /* to center */
padding: 0 4px;
}
fieldset:nth-of-type(3) > legend {
transform: rotate(180deg);
}
I used the font
shorthand property to give the values for the font-size
, line-height
and font-family
properties of the <legend>
elements.
The <legend>
element that adds the text at the bottom border of our design, fieldset:nth-of-type(3)>legend
, is upside-down because of its rotated <fieldset>
parent element. Flip that <legend>
element vertically to show its text right-side-up.
Add an image to the first <fieldset>
element and you get something like this:
Lateral margins can move the text along the border. Left and right margins with auto
values will center the text, as seen in the above Pen. Only the left margin with an auto
value will flush the text to the right, and vice versa, for the right margin.
Bonus: After a brief geometrical detour, here’s an octagonal design I made using the same technique:
Neat technique! Be sure to add
role="presentation"
(details) to prevent assistive technology like screen readers from announcing those elements asfieldset
s andlegend
s, which will confuse the users of those tools.Thanks for Sharing. I was looking for this. :D
Awesome
This reminds me of those “split headers” with a line on either side. I remember how (and this was ages ago!) some solutions used a background color to hide the line beneath the text, but of course that method wouldn’t work on an image or multicolored background. I’d been using the
::before
and::after
tricks, but with some styling, thefieldset
method works too.You Saved me , really really thank you
I was wondering if it was legit to use a
fieldset
+legend
outside of a form to achieve a “labeled border” effect. What I’m hearing is that it wouldn’t be an unpardonable sin to do so, especially as we’re able to mark it as being only done for the sake of presentation.OK, but how do I add text without the border breaking? I want to add text inside a shape border.