How to Skew Images in CSS
In this tutorial, we're going to walk through how we can leverage CSS's transform property in order to create these types of skewed images.
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
  • Complete the Exercise
Video locked
This video is viewable to users with a free Dev Camp account

We're also going to walk through how we can work with the absolute and relative positioning, so that we can have page elements, such as this heading and this navbar, to sit on top of this image.

Now, I will provide an image for you, though you definitely can feel free to use your own images. If you don't have one that you'd like to use, then I have one here, and I'll include this in the show notes. This is one that's going to be for an about page.

large

We can click on save image here, and I'm just going to save it into the backgrounds directory in the project. Click save, and that brings it down, so we have access to it and can work with it. Switching over into the code, what I'm going to do is I'm going to use a combination of inline and external styles.

The reason why I'm going to do that is because if you want to use a background image and you want to use different images for each page, so for example, we have this about page, and say we have a menu page and a contact page. Do you notice how the background image, or the skewed image, changes for each one of them?

Well, if you try to add a background to the CSS file, you'd have to create separate classes for each one of those backgrounds. I don't really want to do that, so the way we can get around that is by actually adding in an inline style.

This is a great example of when an inline style could work quite nicely. What I'm going to do here is I'm going to start off by adding inside of this header-bg div class the inline style. I'm going to say style and then we'll say background-image, and then I want to use a URL.

Inside of the URL and use single backticks here, I'm going to grab images/backgrounds/about-us.jpg. I believe that should give us access to it, and then at the very end put a semi-colon there.

about.html

<div class="header-bg" style="background-image: url('images/backgrounds/about-us.jpg');"></div>

Now, this should give us the background image. Now if you hit refresh, let's see if we have maybe a typo, let's select it. Actually, I know what the issue is, so this is a good one, we're going to click on it and notice how it is finding it and you can click there. It'd give us an error if it was an issue.

large

We need to give it a height, so if I say a height of say, 400px, you can see that it's right there. We're going to do that but we're going to do it separately. We now know that the background image is being pulled in properly.

large

Now if we go and I'm going to add a full set of custom styles here. I'm going to say these are the styles for the Skewed Header. The very first thing I'm going to do is I'm going to grab the skewed-header-wrapper, just that kind of generic class, and I'm going to use position: relative. I'll talk about why we need to do that here in a moment.

Then I'm going to give the height, just like we talked about, of 400px. I'm going to say overflow is hidden. All of these items are necessary for implementing the clip-path that we're going to have.

common.css

/* Skewed header */
.skewed-header {
    position: relative;
    height: 400px;
    overflow: hidden;
}

The reason why we need to use this position: relative is because anytime that you want to have this type of behavior where you have elements that are sitting on top of an image like this, then you need to use what is called a position absolute property.

In order to use position: absolute, the parent element needs to use position: relative. Now that may not make any sense to you if you've never done that before, but it is a rule in CSS.

It's something that I have run into a number of bugs through the years where I was trying to add absolute positioning. I was trying to create something like this and I had forgotten to put position relative in the parent class and so it didn't work.

large

That's something you just always have to know, if you want to have this overlay effect like we're going to build out and you want to use position absolute, the parent element does have to have that value. Now if I hit refresh, you can see we still need to update some values here in the header background.

large

We have the skewed header, now let's come and select the background. Let's go skewed-header and then we want the element inside called header-bg. Inside of header-bg, this is where we're going to start off by saying we want the position: absolute and then we want it at the very top.

common.css

/* Skewed header */
.skewed-header {
    position: relative;
    height: 400px;
    overflow: hidden;
}

.skewed-header > .header-bg {
    position: absolute;
}

We're going to say, I want to use the top property of 0, I want the bottom to be 0, I want the right to be 0 and as you may have guessed, I want the left to also be 0. That's going to give us the ability to have the image sitting flush on all sides.

common.css

.skewed-header > .header-bg {
    position: absolute;
    top: 0;
    bottom: 0; 
    right: 0;
    left: 0;
}

Then I want the height to be 100% and I want the same thing with the width. Now let's add some of our styles for using background images. We already are bringing in the background image inline, but we can still add background image properties here.

common.css

.skewed-header > .header-bg {
    position: absolute;
    top: 0;
    bottom: 0; 
    right: 0;
    left: 0;
    height: 100%;
    width: 100%;
    background-repeat: no-repeat;
    background-size: 100%;
}

So I'll say background-repeat, we want no-repeat. Then we want the background-size to be 100%. We want it to take up the full width. Now let's hit save here, hit refresh, and you can see that is working.

large

Now we have our image and everything there looks nice. Now what we need to do now is to implement our skew. The way we're going to do that is pretty cool and let's test it out here first. What we're going to use is the transform property.

We're going to say transform and I want to use a skewY. This is going to use the y radius and you also have to pass in the value. So skewY and then skewY is going to take in a value. I'm going to say -6deg, just like this. You can see that that gives us a cool little skew element, but we're not done yet.

large

We need to say where we want the transform to happen. So I'm going to say transform-origin and we're going to say top-left. You can see that's working perfectly.

large

That is how you can use the transform property in order to get this to work. Earlier I kind of misspoke, I said clip-path, but we're actually using the skew and the transform property in order to make that possible.

I'm also going to add a filter. So I'm going to say filter: brightness() and the autocorrect here is not helping me out. So I just want to darken this a little bit. I'm going to say brightness and we'll say 50%. That darkened it.

large

Now when we want to have elements sitting on top of it, that will work nicely. I'm just going to grab these transform properties here and put them in the actual code. Now they'll be permanent. I'll hit save, hit refresh and that is looking really good.

Now that we have all of that in place, let's go and let's actually have the content. We'll update the content so that it allows for being able to lay on top of this image. If you look at the about.html right here, we have the skewed-header-content, we have the heading-wrapper, and then a links-wrapper.

large

Those are the class names that we have to work with. Next, we can say that we want to have the skewed-header and then from there we want the skewed-header-wrapper. We want this to sit on top of the image, so here we'll say position: absolute.

There you go, and then we want this to utilize Flexbox, so I'm going to say display: flex, justify-content: center, and then I want the width to take up the full view width. So I'm going to say width: 100vw.

common.css

.skewed-header > .skewed-header-wrapper {
    position: absolute;
    display: flex;
    justify-content: center;
    width: 100vw;
}

What this does is it looks at the viewport, meaning it looks at the window and it says, "I want to take up 100% of that window space." Let's hit save, if you hit refresh, now you can see that that content is now laying on top of the image like we're wanting.

large

Now it's not done yet, we still have a few more styles to implement, but we are getting a lot closer. You can see that now we have the ability to have these nav elements here and the heading is also working as well.

Now that we have this skewed-header-wrapper, what's next? If we look at the about page you can see this is what we just worked on. Now we have skewed-header-content, this is the actual Flexbox container that will hold these elements.

Let's come down here and we'll copy that selector because we're going to be using part of it. Then if you come and grab the content, we'll say that we want the skewed-header-content. We want this to be only 1000px wide.

The top one we want going from edge to edge, but here we're actually having the content, we want to wrap it in 1000px container. This is going to also use Flexbox. We're going to say justify-content: space-between because we want to have a space between the heading and then the nav elements.

common.css

.skewed-header > .skewed-header-wrapper > .skewed-header-content {
    width: 1000px;
    display: flex;
    justify-content: space-between;
}

This is going to be one div, this is another div, and we want the space between to be what fits there. That's going to be how we separate that out. Then we also want to say align-items: center to center them vertically.

common.css

.skewed-header > .skewed-header-wrapper > .skewed-header-content {
    width: 1000px;
    display: flex;
    justify-content: space-between;
    align-items: center;
}

Now coming back, you can see that that is looking gorgeous, I really like the way that that is coming along. We are almost done with this entire heading, so moving down.

large

The next item that we're going to grab is going to be the skewed-header. Let's go the skewed-header.
We have the skewed-header-heading-wrapper, and then the heading-wrapper. If you notice that's really all we have left to do is to style this, so we put that nice little kind of gold block around here.

Let's come back here now that we know the class and we'll grab the skewed-header and then inside of that we're going to go with the skewed-header-wrapper. Inside of that, we're going to go with the skewed-header-content, and lastly and finally we get to the heading-wrapper.

common.css

.skewed-header > .skewed-header-wrapper > .skewed-header-content > .heading-wrapper {

}

Now, technically, you could have just grabbed the skewed-header-content and then the heading-wrapper, and that would have been perfectly fine. I just wanted to make it really clear what element that we're grabbing here.

Now I want to have a background-color of that #CEA135. From there, I want to use dark blue for the coloring, so that's that #11122B. We've talked about border-radius, now I want to show you how we can be even more specific.

common.css

.skewed-header > .skewed-header-wrapper > .skewed-header-content > .heading-wrapper {
    background-color: #CEA135;
    color: #11122B;
}

You notice how in the final design, you notice how this box right here has a little bit of a rounded edge on the bottom-right and bottom-left-hand side, but it's not up here at the top. Well, we can be really specific with our border-radius.

We can say that I want to do a border-radius here but instead of just the regular border-radius, we can actually dictate that we only want it to be on the left and right bottom sides. The property for doing that is going to be border-bottom left radius and for that, I'm going to say 2px.

common.css

.skewed-header > .skewed-header-wrapper > .skewed-header-content > .heading-wrapper {
    background-color: #CEA135;
    color: #11122B;
    border-bottom-left-radius: 2px;
}

Then we want to do the same thing for the right, and then let's also give it a width. So we'll say a width of 175px. We'll have padding all around it or all inside of it of 10px. Lastly, let's align the text right in the center.

common.css

.skewed-header > .skewed-header-wrapper > .skewed-header-content > .heading-wrapper {
    background-color: #CEA135;
    color: #11122B;
    width: 175px;
    border-bottom-left-radius: 2px;
    border-bottom-right-radius: 2px;
    padding: 10px;
    text-align: center;
}

If I hit save here and then hit refresh, you can see that that is working gorgeously. Right here we still have our nice nav component, it has all of its animations, we have our clipped kind of image here and we're able to use the transform.

large

You learned how to use the transform both with the origin and just creating the skew, and you're able to put it all together. Great job if you went through that, this is definitely not a trivial thing to build out.

The first time that a designer handed me a design that had to have this, I'd never built it before and it took me a while to figure out. I'm really happy that I learned it because this is a skill that is really handy, especially right now.

A lot of designers that I've been working with have been putting together some skews like this. Great job if you went through that, you now know how to use transform and skews in CSS.

Resources