Given an image button with borders how to stretch/repeat middle part in CSS for variable length content?


Tags: css,tabs

Problem :

This is similar to Google Chrome tabs style taken from Soda Theme (Sublime Text 2):

google chrome tabs sublime text 2

You see how it has 3 parts to it: rising edge, 2-3px flat middle, falling edge.

Q: How would I, in CSS, "repeat" the middle part and stretch the tab to fit the size of the string?

Image Dimensions: 42 x 28.

If it helps here is the snippet from the .sublime-theme file:

    // Tab element
    {
        "class": "tab_control",
        "content_margin": [12, 3, 12, 3],
        "max_margin_trim": 0,
        "hit_test_level": 0.0,
        "layer0.texture": "Theme - Soda/Soda Dark/tab-inactive.png",
        "layer0.inner_margin": [5, 5],
        "layer0.opacity": 1.0
    },


Solution :

There are more than a few different ways to accomplish this affect, and it really depends on your preference. As you properly postulated, you need to think of this as 3 different parts. As such, the easiest way would be to split it up into 3 different images.

The solution also depends on what your HTML markup looks like. For example, if you only have:

<a class="tab" href="#">My Tab</a>

Then you have only one element you can style to make this works (which makes it much harder).

However, if you have a wrapping element around the tab:

<li class="tab"><a href="#">My Tab</a></li>

You can then use the LI element to help achieve the desired result.

Single Element

In my first example, you only had the single "anchor" element to work with. Examining your image you want to use for the tab, I can see that it has some beveling, and isn't a simple flat color, or a flat color with a simple border. That means we can't achieve that effect with straight CSS, so we will need CSS to tile the image.

You have two options.

Option 1

Split the image into two images, a left and right side, by dividing it right down the middle. Next, in your image editing application, extend your canvas out to the right by, let's say, 200 pixels (or whatever you think the max width of a tab will ever be). Finally, select the farthest right edge (this should be the middle of the tab) and stretch it horizontally all the way to the right border.

What you should end up with is the sloped left side, then an ~200pixel "middle area".

Now you have two images we will call tab-left-side.png and tab-right-side.png. With these two images, you can achieve the tab affect with the following CSS:

.tab {
    background: url(tab-left-side.png) no-repeat 0 0;
    overflow: hidden;
    padding-left: 10px; /* width of the left edge of the tab, before the middle section begins. If you want more horizontal tabbing, add it to this value */
}

.tab:after {
    content: ' ';
    overflow: hidden;
    width: 10px; /* width of the right edge of the tab */
    background: url(tab-right-side.png) no-repeat 0 0;
}

Option 2

This option requires splitting your image into three images. You will have tab-left-side.png, tab-middle.png, and tab-right-side.png. As you can guess, you should split the image up into these appropriately.

Now, you can use the CSS:

.tab {
    background: url(../images/tab-middle.png) repeat-x 0 0;
    overflow: hidden;
    color: white;
    float: left;
    margin: 0 10px; /* must be same as side widths */
}

.tab:after {
    content: '.';
    overflow: hidden;
    text-indent: -999px;
    float: right;
    width: 17px; /* width of the right edge of the tab */
    background: url(../images/tab-right-side.png) no-repeat 0 0;
}

.tab:before {
    content: '.';
    text-indent: -999px;
    overflow: hidden;
    float: left;
    background: url(../images/tab-left-side.png) no-repeat 0 0;
    width: 17px; /* width of the left edge of the tab */
}

Double Element

The double element is accomplished exactly the same way as Option 1 of the Single Element example, except that you don't have to use the pseudo-class selectors. If you are writing code that has to support older browsers that don't support pseudo-class selectors (or at least :before and :after) then this is your only option.

Again, you split the two images up into tab-left-side.png and tab-right-side.png.

Then, your CSS:

LI.tab {
    background: url(tab-left-side.png) no-repeat 0 0;
    overflow: hidden;
    padding-left: 10px; /* width of the left edge of the tab, before the middle section begins. If you want more horizontal tabbing, add it to this value */
}

LI.tab A {
    content: ' ';
    overflow: hidden;
    width: 10px; /* width of the right edge of the tab */
    background: url(tab-right-side.png) no-repeat 0 0;
}

It's virtually the same CSS as was in the Option 1 example, except we changed the selectors.


    CSS Howto..

    How to select an element that has id starting with a digit (css)?

    How to relativize URLs in css files in Hakyll?

    How do I override inline CSS with Class CSS? [duplicate]

    How to properly position DIVS on a page to

    How to display message inline

    How to transform Ruby hash to CSS rule?

    How to remove default border of button in jquery mobile?

    How to use a CSS animation within a JavaScript plugin?

    How to make all cross browser compatible skewed div edges?

    CSS: How to select only the first non-adjacent sibling after the element

    How to have different alignments in one div(nav)?

    If there is too many menu items how to gather them into collapsed menu

    How to align text below an image in CSS?

    How to make a smooth dashed border rotation animation like 'marching ants'

    How to change the width of an HTML upload field with CSS?

    CSS - How do you make text overflow out both ends of a div?

    toggle css as well as show/hide jquery

    How to change default comments pattern in Atom (specifically for CSS)

    How to resize an image cropping it equally on each side with CSS

    How do I disable position:fixed in web pages?

    How to appy font color from li:hover to inner a link text using CSS

    How to bring all elements down with a header slide up/down?

    Flexbox and Bootstrap How to Put Image in Navbar Brand Area

    How to use “css” in the “jsp” in Spring MVC project?

    How to make table by CSS?

    How to get the element position after css-translation

    How to change label color with html and CSS without js?

    How to spin css cube each after each [closed]

    How to get a navbar to display text depending on button clicked

    how to check what css code is invalid using browser plugins [closed]