Semi-transparent slanted background
Asked Answered
C

1

19

I want to create an html element, e.g. a div, which is styled as follows:

  • semi-transparent background-color
  • rounded borders on all edges
  • left side of the div draws a straight line
  • right side of the div draws a skewed line

I'd like to create this in CSS only and wonder if this is possible. So far I came up with two different approaches which have their own drawbacks and are not fully sufficient. You can have a look at those in this fiddle:

https://jsfiddle.net/n4tecna3/

.one-side-skew-1,
.one-side-skew-2 {
  font-size: 20px;
  padding: 2%;
  background-color: rgba(220, 50, 255, 0.6);
  position: relative;
  display: block;
  border-radius: 4px;
  z-index: 2;
  color: #ffffff;
  margin-top: 30px;
}
.one-side-skew-2 {
  border-top-right-radius: 0px;
}
.one-side-skew-1:after {
  height: 100%;
  width: 20%;
  position: absolute;
  top: 0;
  left: 85%;
  display: inline-block;
  content: "";
  background-color: rgba(220, 50, 255, 0.6);
  -moz-transform: skewX(-10deg);
  -webkit-transform: skewX(-10deg);
  -ms-transform: skewX(-10deg);
  -o-transform: skewX(-10deg);
  transform: skewX(-10deg);
  z-index: -1;
  border-radius: 4px;
}
.one-side-skew-2:after {
  border-top: 1em solid rgba(220, 50, 255, 0.6);
  border-left: 0.25em solid rgba(220, 50, 255, 0.6);
  border-right: 0.25em solid transparent;
  border-bottom: 1em solid transparent;
  border-top-right-radius: 4px;
  left: 100%;
  display: inline-block;
  position: absolute;
  content: "";
  top: 0;
}
.container {
  width: 500px;
}
<div class="container">
  <div class="one-side-skew-1">
    <span class="inner-text">One Side Skew With Pseudo Element Skewed</span>
  </div>

  <div class="one-side-skew-2">
    <span class="inner-text">One Side Skew With Pseudo Element Border</span>
  </div>
</div>

Approach 1 .one-side-skew-1 uses a div element with round borders and a skewed, round-bordered pseudo element to create a one-side skewed element in sum. This works great as long as the background-color is solid. For semi-transparent backgrounds you will see an ugly color overlap where the element and its pseudo-element meet.

Approach 2 .one-side-skew2 uses a div element with a pseudo behind it that consists of borders only. It's somewhat hacky but gets close to my desired result. Still, the right does not look nearly as smooth as in the first approach.

Does someone else have a good solution for this problem in CSS only? Or will I have to use a fallback solution with a semi-transparent background-image to solve this?

Carchemish answered 4/5, 2015 at 9:13 Comment(3)
Another posibility (but distorting the div content) here: https://mcmap.net/q/633201/-skew-one-corner-of-imageGermany
@Germany I also wrote a similar answer some time back! This method can be used as a pseudoelement of the element. this way it wont distort.Kish
Problem with approach 2: zooming in with mobile safari (iPhone 5C, latest iOS) causes the pseudo-element to disappear.Soothe
R
17

You can use a pseudo element for all the background and hide the overflowing parts with the overflow property on the element.

This will prevent element and pseudo element background overlapping and allow semi transparent backgrounds:

div skewed on one side and semi transparent background

div {
  position: relative;
  width: 250px;
  font-size: 20px;
  border-radius: 4px;
  overflow: hidden;
  color: #fff;
  padding: 1% 2%;
}
div:before {
  content: '';
  position: absolute;
  top: 0; right: 0;
  width: 100%; height: 100%;
  background: rgba(220, 50, 255, 0.6);
  -webkit-transform-origin:100% 0;
  -ms-transform-origin:100% 0;
  transform-origin: 100% 0;
  -webkit-transform: skewX(-10deg);
  -ms-transform: skewX(-10deg);
  transform: skewX(-10deg);
  border-radius: 4px 4px 6px;
  z-index: -1;
}


/** FOR THE DEMO **/body {background: url('http://lorempixel.com/output/people-q-g-640-480-3.jpg');background-size: cover;}
<div>content</div>
Rimskykorsakov answered 4/5, 2015 at 9:23 Comment(8)
So the 'width: 110%;' on the pseudo element will just draw far outside of the div it belongs to and by hiding the overflow, the div will appear skewed on only one side, right? I just updated my fiddle and it looks great: jsfiddle.net/n4tecna3/1Carchemish
yes @Carchemish that is the point. Is the element supposed to be higher or wrap on several lines?Rimskykorsakov
perfect @Carchemish . Just be aware that if the content is wrapped on many lines, it can be clipped on the right by the slanted edge. You can then compensate with right padding on the parent element.Rimskykorsakov
yes, you're right @Rimskykorsakov . I'll check that for my use case and add the respective padding then if neededCarchemish
@Carchemish I just though : in fact no need to give the pseudo element a bigger width.Rimskykorsakov
I don't know if this is a problem for @jessica, but I can't see any skew using mobile safari on an iPhone 5C (latest iOS).Soothe
@Soothe safari requires the -webkit- vendor prefix. I haven't added any prefixes in the answer for the sake of brievety.Rimskykorsakov
@Rimskykorsakov Of course! Then I'll withdraw my comment. Thank you!Soothe

© 2022 - 2025 — McMap. All rights reserved.