16

I've got a span which goes over a number of lines and has a background colour. I need each of the lines to have a 10px padding at the end. The text will be dynamic so i need a css or js solution rather than just hacking it with nbsp tags (which is how I got the example pictured below)

The picture show the difference between what I have and what i want: padding difference

<h3><span class="heading">THE NEXT GENERATION OF CREATIVE TALENT</span><br/>
<span class="subhead">IT'S RIGHT HERE</span></h3>

h3 {
    margin:0;
    font-size: 42px;}
h3 .heading {
    background-color: #000;
    color: #00a3d0;}
h3 .subhead {
    background-color: #00a3d0;
    color: #000;}

I can't think of any way to do this with css, I was considering using javascript to find the beginning and end of each line and adding a non-breaking space.

Does anyone have any ideas of how to achieve this? Cheers

Alex
  • 357
  • 2
  • 9
DonutReply
  • 3,184
  • 6
  • 31
  • 34
  • 1
    How are you getting the different style on the last line at the moment? / Could you show your current HTML/CSS? – thirtydot Feb 14 '11 at 16:38
  • 1
    @thirtydot he said that he manually added ` ` to this sample of text. – Pointy Feb 14 '11 at 16:43
  • 1
    @Pointy: I guess I worded that first comment badly. What I meant was "in your *first image*, how are you getting the different style on the last line". Although, I have no idea why I want to know.. – thirtydot Feb 14 '11 at 16:45
  • @thirtydot I've added my styles and markup for the header – DonutReply Feb 14 '11 at 16:48
  • @Ollie Bourne: Could you change the markup so that every word is in a `SPAN`? – Gumbo Feb 14 '11 at 16:55
  • @gumbo And add padding to every word? That would mess up the word spacing and be very ugly semantically. Wrapping every line in a span would be an easy solution but the content will be dynamically populated from a cms and I can't ask the client to do this – DonutReply Feb 14 '11 at 17:10
  • @Ollie Bourne: At least it works that way. – Gumbo Feb 14 '11 at 17:35
  • I'm *so close* to a really nice solution. F!%$*ing IE! – thirtydot Feb 14 '11 at 18:09

8 Answers8

9

I've tested this in IE8 (doesn't look too bad in IE7) and recent versions of Chrome, Firefox, Opera, Safari.

Live Demo

Screenshot from Chrome:

Chrome

It got a bit silly and, to be honest, probably more complicated than it's worth - a JS based solution would definitely be easier to understand.

There are so many gotchas with this technique.

CSS:

#titleContainer {
    width: 520px
}
h3 {
    margin:0;
    font-size: 42px;
    font-weight: bold;
    font-family: sans-serif
}
h3 .heading {
    background-color: #000;
    color: #00a3d0;
}
h3 .subhead {
    background-color: #00a3d0;
    color: #000;
}

div { 
    line-height: 1.1; 
    padding: 1px 0;
    border-left: 30px solid #000; 
    display: inline-block; 
}
h3 { 
    background-color: #000; 
    color: #fff; 
    display: inline; 
    margin: 0; 
    padding: 0
} 
h3 .indent { 
    position: relative; 
    left: -15px;
}
h3 .subhead {
    padding: 0 15px;
    float: left;
    margin: 3px 0 0 -29px;
    outline: 1px solid #00a3d0;
    line-height: 1.15
}

HTML:

<div id="titleContainer">
    <h3><span class="indent">

        <span class="heading">THE NEXT GENERATION OF CREATIVE TALENT</span><br /><span class="subhead">IT'S RIGHT HERE</span>

    </span></h3>
</div>

<!--[if IE]><style>
h3 .subhead {
    margin-left: -14px
}
</style><![endif]-->
thirtydot
  • 224,678
  • 48
  • 389
  • 349
  • Genius! I haven't tested it fully yet but it looks like it's got legs – DonutReply Feb 15 '11 at 11:07
  • btw are the two separate h3 and h3 .subhead style blocks part of some kind of css hack or were they accidental? – DonutReply Feb 15 '11 at 11:14
  • They were on purpose separate, but it's not for any reason other than to keep your specified CSS at the top, and add mine at the bottom. This could be more robust if you could split it into two separate `

    ` tags, one for each different style. I didn't spend *too long* on this before, as there were already good answers here.

    – thirtydot Feb 15 '11 at 11:30
  • 1
    I developed your solution a bit further to allow the subheading to flow over multiple lines http://jsfiddle.net/vbeVT/1/ – DonutReply Feb 15 '11 at 13:23
  • Looks good, though you may need a `
    ` between the two `

    ` tags. And it seems much cleaner now it's split into two `

    `. (no need anymore for the more ridiculous stuff I had like `outline`, etc)

    – thirtydot Feb 15 '11 at 13:30
  • http://stackoverflow.com/questions/12330659/same-padding-at-start-and-end-of-each-line – thirtydot Aug 26 '14 at 12:23
  • 1
    Easier way to do it in modern browsers (`box-shadow`): http://jsfiddle.net/thirtydot/HksP2/57/ – thirtydot May 02 '17 at 21:54
7

box-shadow makes it easy!

box-shadow:0.5em 0 0 #000,-0.5em 0 0 #000;
-moz-box-shadow:0.5em 0 0 #000,-0.5em 0 0 #000;
-webkit-box-shadow:0.5em 0 0 #000,-0.5em 0 0 #000;
gabitzish
  • 9,535
  • 7
  • 44
  • 65
2

Here’s a solution that requires each word being wrapped in an additional SPAN element:

<h3><span class="heading"><span>THE</span> <span>NEXT</span> <span>GENERATION</span <span>OF</span> <span>CREATIVE</span> <span>TALENT</span></span><br/>
    <span class="subhead"><span>IT'S</span> <span>RIGHT</span> <span>HERE</span></span></h3>

Then you can style the words individually like this:

h3 span {
    display: inline-block;
}
h3 > span > span {
    padding: 0 0.25em;
    margin: 0 -0.25em 0 0;
}
h3 .heading span {
    background-color: #000;
    color: #00a3d0;
}
h3 .subhead span {
    background-color: #00a3d0;
    color: #000;
}
Gumbo
  • 643,351
  • 109
  • 780
  • 844
  • It works http://jsfiddle.net/t7f89/ well done, but it's very ugly semantically plus it would require the spans to be added in dynamically either in the cms or with js. Full marks for ingenuity though. I'd prefer the nbsp tag method as it's less messy but I might not be able to automate that – DonutReply Feb 14 '11 at 17:49
  • Well Done Gumbo! About semantic, you could generate the 'normal' text server-side and then wrap each word by JS i.e. http://jsfiddle.net/steweb/FJsB5/ – stecb Feb 14 '11 at 18:36
  • +1. Maybe this is "very ugly semantically", but there was a `
    ` and a bunch of allcaps in the markup to begin with. You have to consider the total ugliness. thirtydot's answer uses a `float`, `outline`, relative positioning, and a bunch of pixel-perfect distances.
    – Jason Orendorff Sep 08 '12 at 13:08
1

You could do something like this. Wrap it inside a <p> and set a border-left = to the padding left you'd like to set to the span. About right padding, I don't think there will be a solution without using JS. Btw, I'm still looking for other kinds of tricks

http://www.jsfiddle.net/steweb/cYZPK/

EDIT updated starting from your markup/css http://www.jsfiddle.net/steweb/cYZPK/1/

EDIT2 (using JS..mootools) http://www.jsfiddle.net/steweb/Nn9Px/ (just tested on firefox...need to be tested on the other browsers.. explanation asap :) )

stecb
  • 14,478
  • 2
  • 50
  • 68
  • That's an interesting solution for getting the padding at the beginning of each line but it doesn't help with the padding at the end of each line – DonutReply Feb 14 '11 at 17:05
  • Well.. that's the hardest challenge :D ..later I will think about it a little more ;) – stecb Feb 14 '11 at 17:07
0

Here's a way to do it without the extra mark up - though it does require an image. http://codepen.io/DeptofJeffAyer/pen/FiyIb

Jeff Ayer
  • 74
  • 6
0

I would highly recommend using Split Lines JS: https://github.com/jeremyharris/split_lines

The issue with tags is that it wraps "inline" meaning from start to finish. So if you have a fixed width and your span automatically goes onto a second line, that line of text will be wrapped with the first line and share the span. To get around this you need to span each line of text separately. For example:

<span>line one</span>
<span>line two</span>

This isn't an easy option if the text you wish to span separately is automatically generated from Wordpress or similar... To get around this use the JQuery script above.

~

Another way to get round it (although may not be ideal) is to simply add display:block; to you spans css class:

span { display: block; background-color: #333; color: #fff; }

This will span the entire block similar to a button.

Hope this helps.

leannekera
  • 17
  • 2
  • 9
0

why not just add padding-right:10px; to the container?

derekcohen
  • 1,514
  • 4
  • 17
  • 34
  • 2
    Because he wants the padding to appear in the running text as it word-wraps, with that resulting jagged edge as shown in the sample. Putting padding on the container will not get the result shown. – Pointy Feb 14 '11 at 16:41
  • 1
    adding padding to the container will only add padding to the beginning of the first line and the end of the last, which would miss out the lines in between where the text wraps. – DonutReply Feb 14 '11 at 16:52
0

Even if is not 100% following your design concept, I think this is the only solution if you want to stick with CSS.

h3 span {
  /* cross browser inline-block */
  display: -moz-inline-stack;
  display: inline-block;
  zoom: 1;
  *display: inline;

  padding:0 10px;
}

The inline-block property will make your element expand based on it's content size, so it behaves like an inline element but also have the block property which lets you apply the padding.

Hope that helps