There are many different ways of designing tabs, and many different approaches to styling tabs to match the design. Your requirements might include slanted edges, rounded edges, borders, or a mix of all these things. You might want to add shadows to all of your tabs, or only the active tab, or only the active tab and the last tab, to try and create a stacked appearance. You might want them to contain multiple or single lines of text, or even images.
Recently, I was working on implementing a design that used tab shadows with slanted edges (essentially adding a triangular shadow effect positioned to the right of a rectangular tab). After doing some research, I found that there are several different methods you can use to create this:
- Create triangles from CSS borders and overlay them onto rectangular tabs
- Create a pseudo-element copy of each rectangular tab, and rotate it using transform (skew)
- Use SVG trapeziums as entire tabs (this requires creating two SVG elements – one with and one without the shadow)
- Use an image of a triangle to overlay on top of the tabs, or use an image of a complete tab (e.g. as an SVG fallback)
We’re going to go through each of these in turn, and talk about the merits and drawbacks of each.
Method 1: Creating triangles using CSS borders
This is probably easiest to explain visually. If you create a div and set your borders to be 4 different colours, you will find you get something similar to below:
There are two ways you can use this to your advantage for making tabs. The first way is to cut out a trapezium shape to create an entire tab with slanted edges, and the second is to cut out a triangular shape and overlay this as a shadow.
How do you get a trapezium shape? Simply set the height equal to zero, remove the top and left borders, and make the right border transparent.
You can then control the angle of the slant by changing the thickness of the right border. You can control the height of the trapezium by changing the thickness of the bottom border, and the width of the trapezium by the width of the div.
If you’ve had trouble visualising how we got to this point, there is a lovely article with lots of diagrams. An example of the code for this can be found here:
How can you create a triangle shape? Exactly the same as above, except you also set the width equal to zero.
Which is better? Using trapeziums has some obvious drawbacks:
- Zero height means that content inside the div will be overflowing it’s container (interestingly the behaviour is still mostly normal e.g. you are able to center vertically using line height or margins)
- If you want to have the main rectangular part of the tab a different colour to the slanted edge shadow, you will have to overlay another div using z-indexing – so you might as well just overlay a triangle instead
- There is no way to have a border around your tab, as we are already using the border to make the shape and colour of the tab.
With the other approach of overlapping triangles, the inability to have borders still remains a problem. You can however set borders on the rectangular part of the tab, which you’re overlaying the shadow on top of, so only getting a border on the slanted edge would be a problem.
It should be mentioned that it’s quite simple to slightly overlap all of your tabs (by default the tab created last will appear on top). However, if you have no borders, this will make your tabs look badly defined.
So if you want to overlap your tabs slightly – use a triangle overlay to the right of the rectangular tab, and then set a border on the left side only.
Method 2: Pseudo-elements and transform (skew)
Another way of creating slanted edges on a div involves creating a pseudo-element (using :before or :after on your div). This is essentially a clone of the current div that you can rotate using transform and transform-origin, and place behind the normal rectangular div using z-indexing. You lose the corners of the rotated block when the height or width is set, so you only keep the desired part of it for the slant.
.tab { float: left; border: 5px solid black; text-align: center; background: #c5bbf7; position: relative; width: 100%; } .tab:after { position: absolute; top: -5px; left: 12px; transform: skewX(20deg); transform-origin: 100%; content: ''; z-index: -1; height: 100%; width: 100%; background: #342c59; border: 5px solid black; }
As you can see, we can create the style of tabs we want by using transform:skewX(angle) and transform-origin:100% to rotate the clone to match the desired angle of the slanted tab. We then use position: absolute and z-indexing to ensure this is behind the rectangular tab showing the tab content. Finally, we move the margin of the pseudo-element div slightly to the left to hide the top left hand corner of the rotated clone, so that only the one desired side is slanted.
We wanted the triangle shadow edge to be a different colour to the main rectangular tab, and for the tabs to be overlapping, and to also have the ability to set borders if we want. To achieve this, I had to use a wrapper element and further z-indexing, but if you don’t have all these requirements, you can use a simpler approach without it.
.wrapper-active, .wrapper-inactive { width: 120px; height: 80px; display: inline-block; } .wrapper-active { position: relative; z-index: 1; } .wrapper-active > .tab { background: #8671ed; }
You can access the full code here – follow the link to see it in action and play around with the code for your understanding! Alternatively, if you just want to have a quick look over the code, and see what the tabs look like, you can use the code pen embed below:
Method 3: SVG trapezium
Another approach is to use SVG to create the shape we want. If you’re unfamiliar with SVG, this article could be a good place to start.
Similarly to using the border approach for CSS, there are two different ways we could go about this:
- We could create two SVGs, each being a complete tab (active and inactive), and use them as appropriate
- We could create a triangle as an SVG and overlay it onto the active tab.
Generally, it’s best to avoid unnecessary z-indexing and overlaying, where a practical solution without exists. So for this reason, I’d recommend the first approach.
How do you make an SVG? Simply use a drawing tool such as Adobe Illustrator or Sketch to design it, and when you save it, go to ‘Save As’ and select an SVG file type.
How do I include it in the code? There’s a great article here about different approaches. Whatever approach you choose, it’s good practice to be consistent about it as you add more SVG to your website. We are using ReactJS, so we use a tag inside an svg-utils component, which we just import and use as appropriate in our codebase.
How do I format the text inside my tab? There’s a nice article here with an example of some text inside an SVG, and details on how to format the word and letter spacing. One of the advantages of using SVG is that it is very easy to customize (add borders, different coloured shadow etc) either in the SVG itself or with CSS.
Another advantage of SVG, is that (as the name suggests), it is truly scalable, unlike including certain types of images. A disadvantage is that if you make a complicated design using SVG it can have a large file size, and lots of complex SVGs thereby introduces more overhead. In addition to this, SVGs are not supported in some older browsers (e.g. IE8), so depending on the range of browsers you support, you may find you need to introduce a fallback.
Method 4: Image overlay
So the final approach to look at is a simple, but limiting one: using images.
You could either: use an image purely for the triangular shadow effect and overlay this onto your tab, or create the entire tab as an image.
The main drawback of this is customisability and versatility. Once you have set your image, you can only easily update the tab design by replacing with a new image. In addition to this, using unnecessary images increases the size of your web application and it’s overhead more than you would otherwise need to.
One of the advantages is browser compatibility – you will run into a lot less issues in old browsers than with other approaches. But if you typically don’t support these old browsers as very few people use them, then this isn’t a huge concern.
Concluding thoughts
We decided to use the first approach discussed – hijacking the CSS border property to create triangles and overlay them onto the tab. This worked well for us as we did not need a border around the shadow effect on the slanted edge, and we managed to implement it without z-indexing (which would have been required for the pseudo-element approach).
In addition, it has great cross-browser compatibility (IE 4.0, Chrome 1.0, Firefox 1.0, Safari 1.0, Opera 3.5 and up) and does not significantly increase overhead and page load times (like introducing image files could).
However, you may find a different method listed above works best for you – perhaps you find it easier to implement, you have a different set of design criteria to meet, or you have different needs in terms of browser support etc.