CSS Trick: How To Get Trapezoidal Images For Your Website

Have you ever wondered how a certain effect is achieved on a website? You are not alone.

This is a question which every web designer wakes up and goes to sleep with. That’s our inborn curiosity.

Same happened to me yesterday.

A friend of mine, who designs visual brand identities, showed me the site of a prospect he recently contacted:

Their site was unfinished(and in Polish), so I couldn’t understand a thing. So I skipped reading the copy and jumped to analyzing the layout and how the whole page holds up graphically.

(Yes, I do that all the time, because just like you, I want to know what makes web sites look good or bad.)

What got me interested there was the shape of every section image. Untypical of the usual rectangularity of the web, they had trapezoidal images!


And the slant was also responsive—it kept its angle and stayed crispy even in smaller sizes… hm, but how?

“I wonder how they did this…”

That’s what I thought immediately.

At first I assumed each picture used as a section image had slanted edges done beforehand. It was either cut and left transparent or had these white triangles applied in the corners.

But wait a second, somebody editing all the images manually? Impossible.

Another option would be to use a <canvas>, get the bitmap data with JavaScript and then paint the slants on top of it? Why do I always think of such complex solutions?

So I stopped and tried to think rationally for a second:

  1. This is a theme. Meddling with the images every time would be unsustainable. Who would make images in trapezoidal shape if they could be doing something more meaningful?
  2. Even if automated, getting the image in the trapezoidal shape shouldn’t be that hard. I doubt somebody would try to use JavaScript and more complex code than needed, if this could be achieved with less effort. Maybe CSS only?

Scrolling to the bottom I saw that even the interactive map pane had these.

So I’m left with the only viable hypothesis of overlaying the images (and containers, as we saw with the map pane) with something that makes them appear having their opposing angles cut off.

Thinking in shapes and layers I would expect this to be either:

  • a trapezoidal white frame covering the section images or
  • triangular elements applied in each corner

Ok, I’m certain something is being overlaid. Now I need some hypotheses for how it may be achieved, so I know what to look for.

  1. If it were an image frame superimposed over the image it could be either an SVG object, or PNG with a transparent cutout.

  2. If triangular elements were applied to the container in real-time, the solution could be either:
    • CSS 3d transformations of an absolutely positioned div with the color of the background (is that even possible?)
    • :before and :after elements with borders and negative top and bottom margins (or absolute positioning)
    • SVG or PNG triangle images

For the image hypothesis I could search the resources tab and see if any images of that kind are loaded. For the overlaying of elements hypothesis I should find the container of the section image.

In any case I should search for the CSS of the section image or any of its parent containers and see what’s happening there. <- This seems like a more reasonable place to start. Let’s go!

Code mining starts

I right-clicked on the section image and selected “Inspect element”. Turns out what I’ve clicked on is part of a slider and the image is actually a background to its outwards most container.

Here is how the mark-up looks:

<div class="headerLine">
    ... <!-- some more wrapping containers -->
    <div class="slider">
        ... <!-- here go slider contents -->

Analyzing the code of the page I noticed that the theme wraps the start of each section (including the header) in what it calls “lines”, meaning you have a “header line” and then more “lines” for each its subsequent section.

Time to read the styles for the headerLine class and… “Eureka! I found it”: the effect was achieved with nothing but plain old CSS borders.

But how?

How to use CSS borders to create the illusion of trapezoidal images

The solution turned out to be the following hypothesis:

If triangular elements were applied to the container in real-time, the solution could be :before and :after elements with borders and negative top and bottom margins (or absolute positioning)”

Speaking of :before and :after, here is what I found in the headerLine:after class rules:

content: "";
z-index: 1;
position: absolute;
bottom: 0;
left: 0;
width: 100%;
border-bottom: 150px solid white;
border-left: 3000px solid transparent;

Let me explain this line by line:

  1. content: "";
Because the :after element is a pseudo element it doesn’t have content when it is initialized. For a border to be shown around something, first there must be “something”. Hence the empty string, which is still considered a value.
  2. z-index: 1;
We want the triangle to create a cutout effect, so we have to hide part the image, hence one level up.
  3. position: absolute;
    Get absolute positioning control over the object.
  4. bottom: 0; and left: 0;
Put this object on the bottom left of … what?
Because pseudo elements are treated as belonging to their parent element headerLine must have position: relative; set, too. This way the absolutely positioned headerLine:after (the triangular looking object) would be contained in the area of headerLine, thus not covering anything else besides what we want it to cover—the background image
  5. width: 100%;
    Translates as: “Make sure the slanted cutout goes from edge to edge of the headerLine
  6. border-bottom: 150px solid white;
    Here starts the magic: create a bottom white border with a height of 150px.
  7. border-left: 3000px solid transparent;
    Create an invisible (but still present) left border with a width of 3000px.

That’s the code. But still the question stands:

What makes the slant effect possible?

It all lies down to the way browsers draw borders.

First, by default, borders are applied at the edge of a container.

Second, the key to the effect we are observing is in the way borders join at each corner.

Thick borders

Borders meet at a 45º angle at every corner

So, when you use different sized borders, this happens:

irregular borders

  1. Content area (the white square) gets pushed away from the thickest border.
  2. Because there is no border on the right you get the straight edge cut of the top and bottom borders there
  3. And the most interesting part—the left border of 100px actually cuts the other two at an angle different from 45º.

So, back to our example from the start:

To achieve this bottom slant there should be a huge transparent border (so that it doesn’t hide the image below) coming from the left and cutting on the bottom one.

Here is how a 300px border from the left looks like:
A  small cut of 300px

That’s not the effect the designer intended from the beginning. That’s why, to reduce the angle of the slant, in the original code they use 3000px for the left border.

This effect is fits the practices of responsive design very well, because the angle of the cutout stays the same, all time. That happens, because the relationship between the two border sizes would always be constant, as long as they are specified in the same units.

But why not apply the borders directly to the headerLine element and skip the pseudo elements?

Let’s apply the headerLine:after CSS border rules to .headerLine:
Content get's pushed out

Left border reduced to 300px for demonstration purposes

Borders will push the content out of the viewport, which ruins the effect. Transparent or not, the left border of 3000px exists and it has to go somewhere.

You saw how using a bit of knowledge and CSS trickery you can achieve a lightweight, but still impressive, effect. Experiment with the ratio of border sizes or border on which borders you hide or you make transparent and you’ll be able make something new out of what you learned from this post. Speaking of learning,

Fancy CSS tricks are cool, but..

They are just a tool in your toolkit as a front-end developer. Yes, if you do your job at this level only, you are not a web designer. Web design goes beyond the mere overcoming of technical limitations.

The problem is that most budding web designers have the inclination of worrying about code too early. They start with the intention of becoming web designers, but obsessed with just code they linger at the level of front-end development instead of progressing further.

HTML&CSS are just the ground level of your work. Front-end development is something that should be part of your toolbox as a designer, but you should not stop there.

Would you like to know what happens when HTML&CSS end and design starts?

Get my free course “Web Design Beyond HTML&CSS” and level up!