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 exacty works the display: flex property on a container div and the flex property on its inner div?

    Fixed Header Scrollable Table - How to preserve horizontal scroll position using css jquery on page loads

    How to set Bullet colors in UL/LI html lists via CSS without using any images or span tags [duplicate]

    jQuery, how can i do to toggle a margin

    How Do I set this PHP printed HTML form to stay within

    tags?

    How can i apply css stylesheet to single specific element?

    Horizontal navigation menu - how to increase size of
  • on hover
  • How I can apply css to part of my jQuery result?

    How to stretch an element out vertically so that it is always at least as tall as its sibling?

    How to make three columns all the full height of the page?

    How to create that background on my page with css [duplicate]

    CSS: How to change colour of active navigation page menu

    How do CSS sprites speed up a web site?

    How can I highlight position in nav bar for single-page website?

    How to achieve this bevel button in CSS?

    How to increase a counter variable after a callback of a setTimeout-function?

    How to use externel CSS and (static) images in Go, Google App Engine

    How to read CSS specification?

    How can I get a box shadow to start below a thick border?

    How style DIV when the id inclue strings in php?

    How do I fade in a div that has a set opacity?

    How to set same height each list items?

    How to write this css in shorter way? see example

    How to add image at right bottom div using css

    How to prevent the background image from getting blurry

    How to reduce the gap between HTML5 video tag

    CSS: How to use vmin unit in IE9?

    CSS: How do I centre an element relative to its parent while right-aligning its sibling?

    How to place a div at top center position of a page using css…?

    How to extract text from contenteditable div (but not html tags)