0

I need to give a link background styling. As the width will vary I need to use 2 images, which is why I have a span within my link.

Ive also needed to float the link left, which means I have to set paragraphs to clear both.

My solution works but it seems like a lot of css and adding extra html elements. Is there a more elegant solution?

http://jsfiddle.net/p9aXg/16/

<p>Here is some text Here is some text Here is some text Here is some text Here is some text Here is some text Here is some text Here is some text Here is some text Here is some text </p>

<a href="#" class="my-link"><span>   This is a link sdafsdafsdaf   </span>
</a>

<p>Here is some text Here is some text Here is some text Here is some text Here is some text Here is some text Here is some text Here is some text Here is some text Here is some text </p>

a {
    background: url("http://smartpeopletalkfast.co.uk/body-link-bg.jpg") 100% 50%;
    line-height: 50px;
    float: left;
}
a span {
    background: url("http://smartpeopletalkfast.co.uk/body-link-bg-2.jpg") no-repeat;
    height: 49px;
    display: block;
    padding-left: 20px;
    padding-right: 40px;
}
p {
       clear: both;
}
Evanss
  • 23,390
  • 94
  • 282
  • 505
  • `border-image` is the 'right' solution to this - but support for it is still not great. Where does this have to work? Support matrix: http://caniuse.com/border-image and toolkit: http://border-image.com/ – Ben Hull Aug 25 '13 at 13:40
  • Also, you can use a single image and 'CSS Spriting' to put both ends of your image in a single image file, like so: http://css-tricks.com/examples/Sprites+SlidingDoors-Button/ – Ben Hull Aug 25 '13 at 13:43

3 Answers3

1

If you use "display;inline-block" instead of floating, you can remove a bit of the CSS.

See the updated fiddle here: http://jsfiddle.net/p9aXg/19/

a {
     background: url("http://smartpeopletalkfast.co.uk/body-link-bg.jpg") 100% 50%;
     display:inline-block;
}

a span {
    background: url("http://smartpeopletalkfast.co.uk/body-link-bg-2.jpg") no-repeat;    
    line-height: 50px;
    display: block;
    padding-left: 20px;
    padding-right: 40px;
}

As a general styling note, you should always try to avoid floating if you can. When you float an element, it takes it out of the flow of the page. This typically forces you to float other elements to make them line up as if they were in the flow of the page. I've seen it snowball to the point where every element is floated, which is simply an unnecessary headache.

Using inline-block instead of float will work most of the time. See the following links for more information: http://joshnh.com/2012/02/07/why-you-should-use-inline-block-when-positioning-elements/

float:left; vs display:inline; vs display:inline-block; vs display:table-cell;

http://www.vanseodesign.com/css/inline-blocks/

http://www.ternstyle.us/blog/float-vs-inline-block

Community
  • 1
  • 1
htxryan
  • 2,871
  • 2
  • 21
  • 21
  • OK great. Is there a way to get around needed the span within the link? – Evanss Aug 25 '13 at 13:26
  • No, the span is required for anywhere you need a dynamic-width background image. You could use javascript to set the width, but that is much messier. A span is the way to go here. – htxryan Aug 25 '13 at 13:29
  • @RyanHenderson - inline-block also have some caviats to it (like adding extra space unless you set `font-size:0` etc.), i'm using floats a lot and never had problems with it. It just a matter of knowing what you are doing – Tomer Aug 25 '13 at 13:31
  • @fatman True. I didn't mean to say that you should never use floats. But many developers use float as a first instinct, which can cause other issues. Float certainly has its uses. – htxryan Aug 25 '13 at 13:36
0

I would use one background image and make it adjust

DEMO jsFiddle

a {
    background-image: url("image.jpg");
    background-repeat:no-repeat;
    background-size:90% 70%;
    background-position:center;
    line-height: 50px;
    padding:20px;
}
Kevin Lynch
  • 24,427
  • 3
  • 36
  • 37
  • `background-size` not supported in *<=IE8, and judging from the fact he is not using CSS3 i'm guessing he needs to support it. – Tomer Aug 25 '13 at 13:36
  • This isnt a good solution for me as it stretches the background image and so changes the border radius. – Evanss Aug 25 '13 at 13:36
  • 1
    This doesn't really work. The background image is simply being stretched. See this fiddle to see an exaggerated example: http://jsfiddle.net/p9aXg/21/ – htxryan Aug 25 '13 at 13:39
  • What browsers do you need to support? you haven't specified. Slicing images for buttons is 10+ years old – Kevin Lynch Aug 25 '13 at 13:59
0

It's possible to do this with no images and no extra elements, if you embrace 'progressive enhancement' across the range of browsers which you support. Here's an example: http://jsfiddle.net/Rt2Wa/4/

This uses CSS3 techniques to achieve a result that's as nice as your example in modern browsers, and produces a flat-but-beveled link in IE 7 & 8.

There are a few techniques at play here:

  • display: inline-block (mentioned by Ryan Henderson - very useful!)
  • border-radius
  • background gradient
  • :after pseudo-element
  • CSS triangles (created with a border effect).

Here's the basics of the effect (see the fiddle for a version with the vendor-prefixed styles where applicable):

a:link {
    background-color: #18A580;
    background: linear-gradient(to bottom, rgba(29,186,144,1) 0%,rgba(24,165,128,1) 100%);
    box-shadow: 0px 1px 2px rgba(50, 50, 50, 0.35), inset 0px 0px 1em 0px rgba(255, 255, 255, 0.4);
    border-radius: 0.3em;
    border-top: 1px solid #67D0BF;
    border-bottom: 1px solid #18805B;
    color: #FFF;
    display: inline-block;
    padding: 0.45em 0.75em;
    text-decoration: none;
    margin-bottom: 0.8em;
}

a:link:after {
    content: '';
    display: inline-block;
    width: 0px;
    height: 0px;
    border-style: solid;
    border-width: 0.25em 0 0.25em 0.5em;
    border-color: transparent transparent transparent #FFF;
    margin-left: 0.75em;
}
Ben Hull
  • 7,524
  • 3
  • 36
  • 56
  • A flat appearance in IE8 and earlier is ok, but wont IE9 also have a flat appearance? http://caniuse.com/css-gradients – Evanss Aug 25 '13 at 14:32
  • Sorry, yes, you're right. IE9 supports box-shadows and border-radius, but not background gradients. I've updated the fiddle to include an additional inset shadow which will give a more 'raised appearance in IE9. – Ben Hull Aug 25 '13 at 15:37