3

I have a css class for centering a heading, and adding vertically centered lines on either side. Problem is, it uses css3 background properties, and not every browser supports those. So I'd like to simplify this for cross browser compatibility, but am not sure how to do that.

Is there a simpler way to achieve this, without the css3 background (and without adding any extra elements or static heights/widths)?

demo here

.section-heading {
  display: table;
  white-space: nowrap;
}

.section-heading:before {
  background: linear-gradient(to bottom, black, black) no-repeat left center / 95% 1px;
  content: "";
  display: table-cell;
  width: 50%;
}

.section-heading:after {
  background: linear-gradient(to bottom, black, black) no-repeat right center / 95% 1px;
  content: "";
  display: table-cell;
  width: 50%;
}
<h2 class="section-heading">Example</h2>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
  • Weird thing is that it doesn't work when I just specify a black background.. –  Oct 01 '13 at 10:48

7 Answers7

6

You can use fieldset and legend, it's not very beautiful code but you don't need CSS3

http://jsfiddle.net/dASCv/9/

fieldset {
  text-align: center;
  border: none;
  border-top: 1px solid black;
}

legend {
  padding: 20px;
}
<fieldset>
  <legend>
    <h2>Example</h2>
  </legend>
</fieldset>

OR this other method whit :after and :before

http://jsfiddle.net/dASCv/10/

div {
  text-align: center;
}

h2:before,
h2:after {
  border-top: 1px solid black;
  display: block;
  height: 1px;
  content: " ";
  width: 40%;
  position: absolute;
  left: 0;
  top: 1.4em;
}

h2:after {
  right: 0;
  left: auto;
}
<div>
  <h2>text TEXT</h2>
</div>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
Donovan Charpin
  • 3,567
  • 22
  • 30
  • It does look a little different though. I think I'd like to stay closer to the h2 element, since that makes a little more semantic sense. I'm already not too thrilled about using display:table, and moving even further away from that would not be preferable in my opinion.. –  Oct 01 '13 at 10:51
  • +1 for an innovative answer. But semantically, it may not be advisable. – Abhitalks Oct 01 '13 at 10:58
  • I have update with a second method which has better semantic :) – Donovan Charpin Oct 01 '13 at 11:02
  • Thank you. Unfortunately it still requires an extra element and doesn't dynamically adapt to the width of the text.. –  Oct 01 '13 at 18:12
  • You cannot go with pseudo elements, no extra tags, no background . with h2 only and a text node inside it, it is not possible with css 3, – Arun Aravind Oct 10 '13 at 11:26
3

There is my best try.

I have a little isue that I have corrected in Chrome; but I really don't know even why it works.

The CCS is

.test {
     display: table-row;
     white-space: nowrap;
     line-height: 0px;
}

.test:before,
.test:after {
     border-color: transparent;
     border-top: solid black 1px;
     border-left: solid transparent 1px;
     border-bottom: solid rgba(0,0,0,0.01) 11px;
     border-right: solid transparent 1px;
     content: "";
     display: table-cell;
     width: 50%;
}

.test:before {
     border-right: solid 30px transparent;
}
.test:after {
     border-left: solid 30px transparent;
}

I am using the border to display the black line, and to have it positioned in place I have reduced the height of the table to 0.

fiddle

In the fiddle, I have kept your original demo, so that you can compare side by side.

And now, the weird part. change rgba(0,0,0,0.01) in the border bottom to rgba(0,0,0,0.001), and it will break (at least in Chrome).

I really would like to understand that ...

new answer

All the above was asuming that the requirement was to have a transparent style (that is , that it was posible to set a background that could be seen thru the h1. If this is not the case, there is another posible solution, using box-shadow instead of gradient barckground:

.test {
  display: table-row;
  white-space: nowrap;
}

.test:before,
.test:after {
  border: solid white 10px;
  content: "";
  display: table-cell;
  width: 50%;
  height: 10px;
  line-height: 10px;
  box-shadow: inset 0px 5px white, inset 0px 6px black;
}

.test:before {
  border-right-width: 10px;
  border-left-width: 1px;
}
.test:after {
  border-left-width: 10px;
  border-right-width: 1px;
}

new demo

vals
  • 61,425
  • 11
  • 89
  • 138
  • Interesting! You can simplify it to this: http://jsfiddle.net/U4tKn/1/. Only the padding on the side of the header isn't working in this one, don't know how to get that.. –  Oct 15 '13 at 09:42
  • Also, in chrome it is probably rounding the bottom border's opacity to 0. –  Oct 15 '13 at 09:43
  • I found out that you can apply padding on the side like this: http://jsfiddle.net/U4tKn/2/. Only thing remaining is pulling the lines to the sides of the container like the original.. –  Oct 15 '13 at 09:50
  • It can be done with transforms (http://jsfiddle.net/U4tKn/3/) but I guess that will go against the requirement about avoiding CSS3 ... – vals Oct 15 '13 at 10:03
  • Ah, I hadn't thought about that. I updated the transforms with the other prefixes: http://jsfiddle.net/U4tKn/4/. I guess this is probably the only way to do it. Thanks for the help! –  Oct 15 '13 at 11:34
  • I am little bit deceived about ending using a transform ... I would like to find a less "CSS3" and more "CSS" solution – vals Oct 15 '13 at 18:08
  • http://jsfiddle.net/U4tKn/5/, I was thinking of pulling it to either side with negative margins, but that doesn't work either. I guess because some of the fixed measurements? –  Oct 16 '13 at 15:44
  • I has already explored that posibility. You would need width: calc(100% + 2em) , and your supported browsers isn't any better ... – vals Oct 16 '13 at 16:04
  • This way: http://jsfiddle.net/U4tKn/7/, it works without css3, but it is not dynamic. If there is a way to make the white background adapt to the text in the header, then it would be possible. Maybe setting the white background to the .test class, but then you would have to find a way to make it overlap the border. Any ideas? –  Oct 16 '13 at 16:08
  • Added new answer using box-shadow. Not so much better in old browsers support, though – vals Oct 17 '13 at 17:37
1

1-element solution

FIDDLE

div {
  display: inline-block;
  background: #fff;
  padding: 0 10px;
}

div:before {
  content: '';
  display: block;
  position: absolute;
  left: 0;
  width: 100%;
  height: 20px;
  border-bottom: 1px solid #c2c2c2;
  margin-top: -9px;
  z-index: -1;
}
<div>A header</div>

(NB: for this solution to work, you need to set text-align:center on its parent element)


2-element solution (works over a background image)

FIDDLE

.splitHR {
  text-align: center;
  overflow: hidden;
}

.splitHRText {
  display: inline-block;
  position: relative;
  padding: 0 10px;
}

.splitHRText:before,
.splitHRText:after {
  content: '';
  display: block;
  width: 1000px;
  position: absolute;
  top: 0.73em;
  border-top: 1px solid #c2c2c2;
}

.splitHRText:before {
  right: 100%;
}

.splitHRText:after {
  left: 100%;
}
<div class="splitHR">
  <span class="splitHRText">A header</span>
</div>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
Danield
  • 121,619
  • 37
  • 226
  • 255
  • Sorry, but I'm looking for a way that does not require extra tags. Quote from the question: *and without adding any extra elements or sacrificing functionality*. –  Oct 10 '13 at 11:14
  • sorry, didn't see that bit.. shame though as it's a good method. – Danield Oct 10 '13 at 11:15
  • does it need to work over a background image (ie non-plain color background) - or is that not necessary? – Danield Oct 10 '13 at 11:16
  • It would be nice, but it's not necessary. –  Oct 10 '13 at 11:17
  • @Sam - I added a 1-element solution – Danield Oct 10 '13 at 11:38
  • Thanks, that's the best solution so far. Unfortunately it still requires styling of the parent element. –  Oct 10 '13 at 11:51
  • Yeah, it requires me to reset the text alignment for all other children. A self contained solution is what I'm looking for. –  Oct 10 '13 at 12:12
  • Yeah I know, it's a difficult one. Was hoping that someone here would have a solution to it, but it seems to be pretty impossible. Maybe with some flexbox magic or something, but that's not really something widely supported.. –  Oct 10 '13 at 19:21
0

Please add Prefix for the CSS

For Webkit browswers

 -webkit-gradient 

Firefox

-moz-linear-gradient

IE

filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#cccccc', endColorstr='#000000');

More Details Here http://webdesignerwall.com/tutorials/cross-browser-css-gradient

Dinesh Kanivu
  • 2,551
  • 1
  • 23
  • 55
  • Yeah, I know, I just thought I'd keep it basic for the example. Also, this is not really an answer to my question. Maybe make it a comment? –  Oct 10 '13 at 10:58
0

Using this way also you can achieve the answer, please check this

<p style="display:block; width:100%; text-align:center; 
border-bottom:1px #ccc solid; line-height:3px">
 <span style="background-color:red; ">Examples</span></p>

http://jsfiddle.net/dASCv/11/

Dinesh Kanivu
  • 2,551
  • 1
  • 23
  • 55
  • Sorry, but I'm looking for a way that does not require extra tags. Quote from the question: *and without adding any extra elements or sacrificing functionality*. –  Oct 10 '13 at 11:13
0

css

h2 {
    border-bottom: 1px solid black;
    text-align: center;
    margin: 0;
    padding: 0;
}

h2 span {
    display: inline-block;
    position: relative;
    padding: 0 20px;
    bottom: -15px;
    background-color: white;
}

markup

<h2><span>text Textsssssssssssssssss</span></h2>

You could set the bottom for span in percentage if you set the height for h2.

Arun Aravind
  • 1,238
  • 10
  • 9
  • Sorry, but I'm looking for a way that does not require extra tags. Quote from the question: *and without adding any extra elements or sacrificing functionality*. –  Oct 10 '13 at 11:18
0

you can use this code:

JsFiddle DEMO

HTML:

<h2><span>Title is here</span></h2>

CSS:

h2{
    display:block;
    text-align:center;
    line-height:30px;
}
h2 span{
    background:#fff;
    padding:0 10px;
}
h2:after{
    content:"";
    display:block;
    border-top:1px solid black;
    margin-top:-15px;
}

Update:

you can use this code too: (single element)

JsFiddle

HTML:

<h2>Title is here</h2>

CSS:

h2{
display: table;
margin: 0 auto;
text-align: center;
line-height: 30px;
padding: 0 10px;
background: #FFF;
}
h2:after{
   content:"";
    display:block;
    border-top:1px solid;
    margin-top:-15px;
    position:absolute;
    width:100%;
    left:0;
    z-index:-1;
}
Mohsen Safari
  • 6,669
  • 5
  • 42
  • 58
  • Read the question. No extra elements. –  Oct 10 '13 at 14:09
  • This way the lines no longer dynamically adjust to the height of the text (it sacrifices functionality). Thank you for trying, but unfortunately it is not an answer to my question. –  Oct 10 '13 at 14:36
  • @Sam: are you trying to plow field with spoon? you can give some style to other elements and make it easier for yourself. why you are insist on having style just with single element ? – Mohsen Safari Oct 10 '13 at 14:46