14

I'm attempting to style heading text similar to how your default legend text appears in fieldsets; that is to say, I'd like a strikethrough-like line to come up to, but not through, the text. I can't seem to find any information on how I might accomplish this, and since on numerous other questions Google's always directed me to Stack Overflow for answers, I thought someone here may be able to give me advice.

For greater clarity. I'm attempting to get this effect on header text:

                               Centered Header Text                               

Is there any way to do this?

Meshaal
  • 694
  • 2
  • 7
  • 18

9 Answers9

15

See: http://jsfiddle.net/thirtydot/jm4VQ/

If the text needs to wrap, this won't work. In IE7, there will be no line.

HTML:

<h2><span>Centered Header Text</span></h2>

CSS:

h2 {
    text-align: center;
    display: table;
    width: 100%;
}
h2 > span, h2:before, h2:after {
    display: table-cell;
}
h2:before, h2:after {
    background: url(http://dummyimage.com/2x1/f0f/fff&text=+) repeat-x center;
    width: 50%;
    content: ' ';
}
h2 > span {
    white-space: nowrap;
    padding: 0 9px;
}
thirtydot
  • 224,678
  • 48
  • 389
  • 349
  • Doesn't seem to be supported in Opera (10.63) either. – Meshaal May 13 '11 at 00:42
  • Well, :before/:after work in Opera, so I'm not sure what the cause is. Quite possibly, Opera doesn't like the application of excessive styles to :before/:after, but I'm not sure why. However, your fix seems to work nicely once I remove the 100% attribute from the header (since that causes it to malfunction with floating elements). Thank you! :D – Meshaal May 13 '11 at 01:22
3

Edit:

<h2><strike>&nbsp;&nbsp;&nbsp;&nbsp;</strike>Your Text Here<strike>&nbsp;&nbsp;&nbsp;&nbsp;</strike></h2>

Here's how you can do it with a few simple tags and non-breaking spaces.

I'd use an image and call it a day, but this seemed to work for me:

CSS

  fieldset {
    border-right: 0px;
    border-left: 0px;
    border-bottom: 0px;
    width: 200px;
  }
  legend {
    margin: 0 25%;
  }

HTML

<fieldset>
  <legend>My Text Here</legend>
</fieldset>

That's the only way I could figure out how to do it with css. Note the width is fixed. Once again I wouldn't do this myself.

CSS Cat Does Not Approve

onteria_
  • 68,181
  • 7
  • 71
  • 64
2

With flexbox being supported by all the latest browsers out there, and it being five years since the IE8 requirement was mentioned by the author, I wanted to have some fun building a new solution using that.

A variety of examples getting more complicated:

https://jsfiddle.net/0mL79b4h/1/

https://jsfiddle.net/0mL79b4h/2/

CSS

div {
  display: flex;
  align-items: center;
}

div:before,
div:after {
  border: 1px solid #000000;
  border-radius: 2px;
  height: 2px;

  display: block;

  content: "";
  flex: 1;

  width: 100%;
}

h1 {
  text-align: center;

  margin: 8px;
}

HTML

<div>
  <h1>Example Text</h1>
</div>

<div>
  <h1>Multi-Line<br>Example Text</h1>
</div>

Pros:

  • Uses flexbox!
  • Super simple HTML.
  • Left and right sides can be adjusted for asymmetry.
  • Zero background issues, no inheriting colors, etc.
  • Fluid width.
  • Multi-Line support.
  • Left/Center/Right/Custom Alignment: Just adjust the flex property separately for the before and after elements, higher numbers will dedicate more space to that side. Remove one entirely to left or right align it.
  • Interesting effects by playing with the border style (I actually chose a round border in this example). Set height to 0px and use border-top instead for a generic line.

Cons:

  • Uses flexbox. Call me lazy, but I didn't build in any backward compatibility in this example so it'll look odd on a browser that supports psuedo elements but doesn't support flexbox, although last I checked that was Chrome (Firefox, etc), which are all automatically updated anyway. Might want to use some Modernizr.
moltendorf
  • 21
  • 2
2

I came up with a quick, image-less solution that seems to work pretty well in IE 8+ and other browsers, whilst gracefully degrading in IE 6/7:

<h1>CSS 2.1 EXAMPLE</h1>
h1 { position: relative; text-align: center; }
h1:first-line { background-color: white; }
h1:before {
    position: absolute;
    z-index: -1;
    content: '';
    left: 0px;
    right: 0px;
    height: 1px;
    top: 50%;
    background-color: black;
}

It does come with the following limitations, though:

  • The text must match the overall background colour exactly, otherwise it will look weird.
  • If you want any kind of padding on the text, you need to use non-breaking spaces at either side of the text (see demo).
  • Heading text must always be on one line (works best if fixed width).

Here's a demo: http://jsfiddle.net/AndyE/3tFQJ/

Andy E
  • 338,112
  • 86
  • 474
  • 445
1

Kind of late to the party, but this is my solution: https://jsfiddle.net/g43pt908/

Requires no images, and doesn't depend on a background color.

HTML

<div class="hr-text">
    <span>Some text</span>
</div>

CSS

.hr-text {
    border-top: 1px solid #999;
    text-align: center;
    background-color: inherit;
}

.hr-text span {
    display: inline-block;
    position: relative;
    height: 14px;
    top: -12px;
    font-size: 14px;
    font-style: italic;
    color: #666;
    background-color: inherit;
    padding: 0 10px;
}
Botch
  • 419
  • 5
  • 19
  • Very nice solution! The one problem I potentially see with this is that if it needed to be on a `background-image`, I think it would need to be used with a `fixed` attachment to make sure the image in the `span` lines up with its container's. Where that's not an issue, though, this is definitely the cleanest solution here. – Meshaal Feb 09 '16 at 12:24
1

Here is what I am using on a client's site: http://jsfiddle.net/TPgE4/

Pros:

  • No images needed - renders instantly
  • Uses padding to control space on both sides of text
  • Text can be center aligned, or left/right aligned — just add, e.g., margin-left: 8px or margin-right: 8px on h2 span style definition to make it look good

Cons:

  • Requires use of additional tag such as <span>...</span> inside heading tag
  • Text must fit on one line for good appearance
  • Background color on <span> element must match surrounding background color, so if you have a non-solid background image, gradient or pattern it won't match perfectly
0

I'm not sure if this would suit your need...

h1:before, h1:after {
 content: " ------------- ";
}
kei
  • 20,157
  • 2
  • 35
  • 62
  • Unfortunately not, as it wouldn't stretch to the edge of the document. Something similar may be able to be done with JavaScript, but I'd worry about cross-browser issues (not to mention my desire to keep the site as JS-free as possible, due to my usual over-reliance on it). – Meshaal May 12 '11 at 22:14
  • Giving it another go: http://jsfiddle.net/4BZVt/ This one is centred and spans across the document width. – kei May 12 '11 at 22:25
  • That's a very innovative approach, but it has the same problem as thirtydot's (with an image background, it's impossible to match): http://jsfiddle.net/4BZVt/1/ – Meshaal May 12 '11 at 22:39
0

This doesn't feel like a very good answer, but I'm posting it anyway.

See: http://jsfiddle.net/rFmQg/

<h2><span>Centered Header Text</span></h2>

h2 {
    background: url(http://dummyimage.com/2x1/f0f/fff&text=+) repeat-x center;
    text-align: center
}
h2 span {
    background: #fff;
    padding: 0 9px
}

I don't like it because:

  • You have to use an image.
  • This. (it only works if the backgrounds match)
thirtydot
  • 224,678
  • 48
  • 389
  • 349
  • Yeah, I had considered this, but that's a big issue with me, since there's an image background. If my site used a clean background, it would work great. – Meshaal May 12 '11 at 22:24
  • Did you see my comments on your question? – thirtydot May 12 '11 at 22:46
  • 1
    I got it, based on your answer and kei's redo! The solution was to use the image idea, with kei's redo formatting - but change it to use a table. http://jsfiddle.net/4BZVt/2/ – Meshaal May 13 '11 at 00:16
  • @Meshaal: Oops. I thought by "heading text" you meant `h1`/`h2` tag, so I was working off that assumption. Yes, it's very easy to do if you're [willing](http://shouldiusetablesforlayout.com/) to use [`table`s for layout](http://www.hotdesign.com/seybold/). My second answer is also using `table`s, just the CSS variety that don't work in IE7 and aren't unsemantic HTML. I suppose using a HTML `table` is at least simple and easy :) – thirtydot May 13 '11 at 00:20
  • @thirtydot: Well, I did mean h1/h2 etc - but in the end, I can style any text how I would headings, and as long as the same effect is achieved, I don't particularly mind a little extra code overhead to achieve the effect. Using tables for layout has never been a preference of mine - but I'll fall back on it if necessary. – Meshaal May 13 '11 at 00:25
  • @Meshaal: Well, for what it's worth, here's how I'd probably do it using a `table`, keeping IE7 support. Yes, it's basically the same as your demo: http://jsfiddle.net/QNURQ/1/ Or removing the `.line` class (still works in IE7): http://jsfiddle.net/QNURQ/2/ – thirtydot May 13 '11 at 00:31
0
body { padding-top: 100px; }

div.parent {
    text-align: center;
    border-top: 1px solid #ccc;
}

div.parent div {
    display: inline-block;
    margin-top: -0.8em;
    padding: 0 0.5em;
    background: #fff;
}
<body>
    <div class="parent">
        <div>My Text Here</div>
    </div>
</body>

This is a fluid-width solution that matches your design and should be ok in IE7 (though I'll admit I didn't check). There are a couple of downsides:

  • You lose the fieldset/legend semantics.
  • You can't put a transparent background on the text.

If you don't need it to be fluid-width, onteria_'s solution is probably your best bet.

Dan M
  • 1,765
  • 1
  • 11
  • 17
  • You should make a [jsFiddle test case](http://jsfiddle.net/) of your code to enable people to quickly see if it will work. I can see that this has the same downside that my first answer and another answer has (the transparent background thing), and the OP has already said he can't use it. – thirtydot May 13 '11 at 00:15