Add centered text to the middle of a horizontal rule
Solution 1
Flexbox is the solution:
.separator {
display: flex;
align-items: center;
text-align: center;
}
.separator::before,
.separator::after {
content: '';
flex: 1;
border-bottom: 1px solid #000;
}
.separator:not(:empty)::before {
margin-right: .25em;
}
.separator:not(:empty)::after {
margin-left: .25em;
}
<div class="separator">Next section</div>
Nowadays every browser supports it, and you can ensure compatibility with decade-old browsers by adding respective vendor prefixes if needed. It would degrade gracefully anyways.
Solution 2
How about:
<div style="width: 100%; height: 20px; border-bottom: 1px solid black; text-align: center">
<span style="font-size: 40px; background-color: #F3F5F6; padding: 0 10px;">
Section Title <!--Padding is optional-->
</span>
</div>
Check out this JSFiddle.
You can use vw
or %
to make it responsive.
Solution 3
The way to solve this without knowing the width and the background color is the following:
Structure
<div class="strike">
<span>Kringle</span>
</div>
CSS
.strike {
display: block;
text-align: center;
overflow: hidden;
white-space: nowrap;
}
.strike > span {
position: relative;
display: inline-block;
}
.strike > span:before,
.strike > span:after {
content: "";
position: absolute;
top: 50%;
width: 9999px;
height: 1px;
background: red;
}
.strike > span:before {
right: 100%;
margin-right: 15px;
}
.strike > span:after {
left: 100%;
margin-left: 15px;
}
Example: http://jsfiddle.net/z8Hnz/
Double line
To create a double line, use one of the following options:
1) Fixed space between lines
.strike > span:before,
.strike > span:after {
content: "";
position: absolute;
top: 50%;
width: 9999px;
border-top: 4px double red;
Example: http://jsfiddle.net/z8Hnz/103/
2) Custom space between lines
.strike > span:before,
.strike > span:after {
content: "";
position: absolute;
top: 50%;
width: 9999px;
height: 5px; /* space between lines */
margin-top: -2px; /* adjust vertical align */
border-top: 1px solid red;
border-bottom: 1px solid red;
}
Example: http://jsfiddle.net/z8Hnz/105/
SASS (SCSS) version
Based on this solution, I added SCSS "with color property" if it could help someone...
//mixins.scss
@mixin bg-strike($color) {
display: block;
text-align: center;
overflow: hidden;
white-space: nowrap;
> span {
position: relative;
display: inline-block;
&:before,
&:after {
content: "";
position: absolute;
top: 50%;
width: 9999px;
height: 1px;
background: $color;
}
&:before {
right: 100%;
margin-right: 15px;
}
&:after {
left: 100%;
margin-left: 15px;
}
}
}
example of use :
//content.scss
h2 {
@include bg-strike($col1);
color: $col1;
}
Solution 4
You can accomplish this with :before and :after without knowing the width of container or background color, and using them allows for greater styling of the line breaks. For example, this can be modified to make double-lines, dotted lines, etc.
CSS, and HTML usage:
.hr-sect {
display: flex;
flex-basis: 100%;
align-items: center;
color: rgba(0, 0, 0, 0.35);
margin: 8px 0px;
}
.hr-sect:before,
.hr-sect:after {
content: "";
flex-grow: 1;
background: rgba(0, 0, 0, 0.35);
height: 1px;
font-size: 0px;
line-height: 0px;
margin: 0px 8px;
}
<div class="hr-sect">CATEGORY</div>
SCSS Version:
.hr-sect {
display: flex;
flex-basis: 100%;
align-items: center;
color: rgba(0, 0, 0, 0.35);
margin: 8px 0;
&:before, &:after {
content: "";
flex-grow: 1;
background: rgba(0, 0, 0, 0.35);
height: 1px;
font-size: 0;
line-height: 0;
margin: 0 8px;
}
}
Solution 5
Try this:
.divider {
width:500px;
text-align:center;
}
.divider hr {
margin-left:auto;
margin-right:auto;
width:40%;
}
.left {
float:left;
}
.right {
float:right;
}
<div class="divider">
<hr class="left"/>TEXT<hr class="right" />
</div>
Live preview on jsFiddle.
Related videos on Youtube
Comments
-
Brian M. Hunt almost 3 years
I'm wondering what options one has in xhtml 1.0 strict to create a line on both sides of text like-so:
Section one ----------------------- Next section ----------------------- Section two
I've thought of doing some fancy things like this:
<div style="float:left; width: 44%;"><hr/></div> <div style="float:right; width: 44%;"><hr/></div> Next section
Or alternatively, because the above has problems with alignment (both vertical and horizontal):
<table><tr> <td style="width:47%"><hr/></td> <td style="vertical-align:middle; text-align: center">Next section</td> <td style="width:47%"><hr/></td> </tr></table>
This also has alignment problems, which I solve with this mess:
<table><tr> <td style="border-bottom: 1px solid gray; width: 47%"> </td> <td style="vertical-align:middle;text-align:center" rowspan="2">Next section</td> <td style="border-bottom: 1px solid gray; width: 47%"> </td> </tr><tr> <td> </td> <td> </td> </tr></table>
In addition to the alignment problems, both options feel 'fudgy', and I'd be much obliged if you happened to have seen this before and know of an elegant solution.
-
willoller over 11 yearsHere's another thread with a no-extra-tags challenge - and a solution! stackoverflow.com/questions/12648513/…
-
Admin over 8 yearsstackoverflow.com/questions/5214127/… is still the best solution.
-
Brian M. Hunt over 6 yearsA useful answer here would employ CSS Grid.
-
tao over 5 yearsAdded an answer (SCSS) which transforms almost any element into a divider without set background and allows setting: color and stroke style (solid, dotted, dashed) of the divider, position of text (left, right, center), as well as the class which applies this (by default
.divider
). -
MatTheCat over 4 yearsGiven current flexbox support I think my answer could gain some visibility.
-
-
dclowd9901 about 14 yearsA more detailed explanation of what I was going for.
-
dclowd9901 about 14 yearsI'm pretty sure
<legend>
takes on the display traits of ablock
orinline-block
element, as it can be padded and margined, which meanstext-align:center
shouldn't work... -
Nick Larsen about 14 yearsI wouldn't call it a hack, but I would test that it works in all browsers you intend to support.
-
willoller about 14 yearsyeah legends are great for semantics - i use them for wrapping radio groups but they are notoriously stubborn
-
Brian M. Hunt about 14 yearsI like this, it looks great on your site, but I couldn't get it to work (I suspect interference from jQuery css). :( But it is really cool.
-
Trey Hunner about 14 yearsI corrected my answer. Unfortunately due to the stubbornness of certain browsers in styling the
legend
element,align="center"
is the only solution I could find that reliably centers alegend
. -
Dänu about 14 yearsfieldset doesn't want to be used like that, it's been hacked into place ;-)
-
Kirby over 12 yearsIt works perfectly and uses <hr /> so what possibly could be wrong with this answer? I say nothing.
-
Mitar over 12 yearsGetting exact top value is a bit hard. It is not exactly -0.5em;
-
imns about 12 yearsI think your h1 is pushing the span down.
-
Nix almost 12 yearsWelcome to StackOverflow, Youri. Instead of a
span
, you could consider using adiv
. It serves the same purpose, except it is naturally a block element. :) -
Peter over 11 yearsThis is a "hack" that employs the different rendering behaviour for DOCTYPE XTHML 1.0 Transitional. If you use DOCTYPE html (for HTML5), it will NOT work.
-
Jonathan over 11 years@Nix Block element inside inline element? No thanks, span is a good choice
-
Nix over 11 years@MrAzulay
h1
is an inline element.span
is nice for wrapping stuff, but the reason I prefer adiv
in this case, is because Youri use CSS to set thespan
todisplay:block;
. I don't see the point of making an inline element into a block element, when there are suitable block elements (div
) readily available. -
Jonathan over 11 years@Nix Isn't that a pretty common thing to do? While putting blocks inside inline is bad practice imo. This is a good post about it skypoetsworld.blogspot.se/2008/10/…
-
Nix over 11 yearsOoops, I mistyped in my latest comment. I agree that you shouldn't place a block inside an inline element, but
h1
is actually a BLOCK element. Sorry for the confusion. Still, I don't see the point of making aspan
into a block element, but fair enough. -
Kelvin over 11 years+1 No need to mess with background color or use tags in unintended ways. One downside is that
.divider hr
width depends on how long the text is. Suggestion:.divider
and.divider hr
widths should be specified inem
units. To gethr
width, use (.divider
width minus # of chars) / 2 . -
Dracorat about 11 yearsDoesn't solve the OP's problem. That creates two lines with text between them. He wants a line that's broken part way through and has text at the broken section, then the line continues.
-
Robert Kajic about 11 yearsIt actually does what the OP is asking for. You can see it at jsfiddle.net/88vgS
-
Robert Kajic about 11 yearsAlso, what is a line broken part way through, with text at the broken section, if not two lines with text in between them?
-
Dracorat about 11 yearsYou should throw appropriate TR tags in there. I think that's what got me confused for a moment. I originally thought for some reason it was on three lines, not three columns. Correct markup probably wouldn't have caused me to see it that way. Regardless, it's definitely a workable solution.
-
Nicholas Petersen over 10 yearsBut this uses tables, that is a NOT ALLOWED! Oh, just kidding. GRIDS have their place, almost all other GUI XML frameworks recognize that and use them everywhere (e.g. WPF / XAML). Thanks for the solution mate! This deserves more than 3 up votes. I suspect people's aversion to the hated tables will be an obstacle though.
-
JimXC over 10 yearsperfect. "Responsive" too
-
iCeStar about 10 yearsSee my answer for a solution that doesn't require you to specify the background color or the width.
-
tehlivi about 10 yearsThis version works better if you are using an image for the line -- or at least it is easier to edit and remain responsive
-
tehlivi about 10 yearsFieldsets should only be used with forms.
-
wloescher almost 10 yearsVery nice work! Can you use your wizardry to create a double line? (Otherwise, I'll just resort to using a tiny repeating background image.)
-
plong0 almost 9 yearsGreat snippet! Thanks :)
-
Dinesh Dabhi over 8 yearsThis is the best answer because it will work without the setting the background , and when you have to set the transparent background
-
Luiz Eduardo over 8 yearsThe first example is simply awesome! Congrats! It should be the correct answer!
-
Farside about 8 yearsElegant solution, though it has one caveat: if there will be no text, you'll still have a gap between lines.
-
Robert almost 8 yearsThis is the cleanest solution in this thread to be honest, the issue with no text can be overlooked since you would want the divider with text always.
-
alaster over 7 yearsVery nice example. Also you can align text to left, center and right and it works as expected - unwanted line will disappear. But you need to remove
text-align: center;
for this to work -
akivajgordon over 6 yearsBest answer considering flexbox support these days
-
Diosney almost 6 yearsTo hide overflowing lines to both sides, just set
overflow: hidden
to the parent and voila, constrained striked lines. -
db0 almost 6 yearsAn updated version that will show a single line without interruption when there is no title: jsfiddle.net/z8Hnz/1901
-
tao over 5 yearsSee my answer for responsive, transparent bg, variable style and height of divider, variable position of text. Can also be applied more than once to different selectors, for having more than one style of divider in the same project, using SCSS. Works with any
font-size
. -
Cameron Hudson almost 5 yearsThe
vertical-center
class no longer exists in bootstrap (4.3.1). Could you please update your answer to sayalign-items-center
? -
cadenzah almost 5 yearsHi, I really appreciate your code snippet. If I put a text with divider other than english (in my case, korean), texts break line in every two letters. Could you figure out why?
-
Vignesh over 4 yearsGreat and reusable solution, like a utility class.
-
TomSawyer over 4 years40% is wrong here. If the text is longer, it would mis-aligned
-
Smaillns about 4 yearsthis is a nice solution
-
Erdem Ergin over 3 yearsI believe placing a span and giving margins to it instead of pseudo classes is more flexible solution for providing margins to text. In this way, it can be used as a single separator component with or without a text.
<div class="separator"><span>Next section</span></div>
.separator span { margin-left: .25em; margin-right: .25em; }
-
MatTheCat over 3 years@ErdemErgin I edited my answer to address your use-case.
-
Christos Lytras over 2 yearsChange
background: rgba(0, 0, 0, 0.35);
withborder-top: 1px dashed rgba(0, 0, 0, 0.35);
to control the line style. -
sohammondal about 2 yearsperfect solution!