CSS: Custom shape having angled borders - html

I have a custom fancy footer created with html and css. See it here: https://jsfiddle.net/fb6qdvrw/
To create the triangles I use :before and :after like this:
#footer .layer-4.bg-secondary:before {
content: '';
position: absolute;
top: 0;
right: 0;
left: 100%;
border-top: 120px solid transparent;
border-left: 120px solid #FFFFFF;
width: 0;
}
#footer .layer-4.bg-secondary:after {
content: '';
position: absolute;
top: 10px;
right: 0;
left: 100%;
border-top: 120px solid transparent;
border-left: 120px solid #ffcf87;
width: 0;
}
The problem I want to solve is the white line / border thickness. I need it to have the same thickness for diagonal and horizontal line. Is this possible in my case? I see I am limited to triangles and rectangles, but I think there must be a solution. For the moment my fancy footer is ugly because of this.

CSS Based Approaches:
Below are a couple of pure CSS based methods to create this shape:
1 - Skewed Transformation:
You can create this shape by using CSS3 skew() transformations.
Required HTML:
All we need is 2 elements inside footer i.e:
<div class="footer">
<div class="top"></div>
<div class="bottom"></div>
</div>
We will then use ::before and ::after pseudo elements for each child element to draw skewed overlays on the respective element:
Output:
Working Example:
body {margin: 0;}
.footer {
position: relative;
padding-top: 100px;
overflow: hidden;
}
.top,
.bottom {
position: relative;
height: 50px;
}
.bottom {
margin-top: 10px;
}
.top::before {
transform-origin: left top;
transform: skew(45deg);
position: absolute;
background: green;
height: 100px;
width: 145px;
content: '';
top: 100%;
right: 0;
}
.bottom:before {
transform-origin: right bottom;
transform: skew(45deg);
position: absolute;
background: blue;
height: 150px;
bottom: 100%;
width: 95px;
content: '';
left: 0;
}
.top::after,
.bottom::after {
transform-origin: left bottom;
transform: skew(45deg);
position: absolute;
background: green;
right: -100px;
left: 100px;
content: '';
bottom: 0;
top: 0;
}
.bottom:after {
transform-origin: right bottom;
background: blue;
right: 100px;
left: -100px;
}
<div class="footer">
<div class="top">
</div>
<div class="bottom">
</div>
</div>
2- Linear-Gradient:
In this approach we will use CSS linear-gradient() function to draw this shape on the element as a background. As we can apply multiple background images on an element so we will divide this shape in small parts and draw them on the element with precisely controlled sizes and positions.
We can divide this shape in 4 parts and draw them each having specific size and position.
Below is a step by step procedure to create this shape:
Required HTML:
We need only one block level element (div) possibly having some class i.e:
<div class="shape"></div>
Step 1:
First of all, lets try to create the long skewed shape on the bottom of the element.
Necessary CSS:
div {
background-image: linear-gradient(-135deg, transparent 50px, blue 50px);
background-repeat: no-repeat;
background-size: 100% 50px;
background-position: right 75px bottom;
}
We will have the following output:
Step 2:
Now we will draw the large triangular shape on the left bottom:
Necessary CSS:
div {
background-image: linear-gradient(-135deg, transparent 50px, blue 50px),
linear-gradient(-135deg, transparent 135px, blue 135px);
background-size: 100% 50px, 180px 200px;
background-position: right 75px bottom, left bottom;
}
This will create the following output:
Step 3:
Now we will draw the upper triangular bar with following CSS:
div {
background-image: linear-gradient(-135deg, transparent 50px, blue 50px),
linear-gradient(-135deg, transparent 135px, blue 135px),
linear-gradient(45deg, transparent 50px, green 50px);
background-size: 100% 50px, 180px 200px, 100% 50px;
background-position: right 75px bottom, left bottom, left 75px bottom 60px;
}
And we will have the following output:
Step 4:
Finally, we will draw the right bottom triangular image:
div {
background-image: linear-gradient(-135deg, transparent 50px, blue 50px),
linear-gradient(-135deg, transparent 135px, blue 135px),
linear-gradient(45deg, transparent 50px, green 50px),
linear-gradient(45deg, transparent 50px, green 50px);
background-size: 100% 50px, 180px 200px, 100% 50px, 150px 100px;
background-position: right 75px bottom, left bottom, left 75px bottom 60px, right bottom;
}
This will create the following shape:
Working Example:
div {
background-image: linear-gradient(-135deg, transparent 50px, blue 50px),
linear-gradient(-135deg, transparent 135px, blue 135px),
linear-gradient(45deg, transparent 50px, green 50px),
linear-gradient(45deg, transparent 50px, green 50px);
background-repeat: no-repeat;
background-size: 100% 50px, 180px 200px, 100% 50px, 150px 100px;
background-position: right 75px bottom, left bottom, left 75px bottom 60px, right bottom;
height: 200px;
}
<div class="shape"></div>
SVG Based Approach:
Polygon Shape:
We can use SVG's polygon element to draw this shape as well:
polygon element draws a closed shape by connecting straight line segments. This element takes single points argument which contains a list of points
Necessary Code:
<svg width="400" height="140" viewBox="0 0 400 140">
<polygon points="0,0 80,100 300,100 330,140 0,140" />
<polygon points="53,50 85,90 305,90 343,140 400,140 400,50" />
</svg>
Working Example:
body {margin: 0;}
svg {
height: auto;
width: 100%;
}
<svg width="400" height="140" viewBox="0 0 400 140">
<polygon points="0,0 80,100 300,100 330,140 0,140" fill="blue" />
<polygon points="53,50 85,90 305,90 343,140 400,140 400,50" fill="green" />
</svg>
Useful Resources:
CSS3 Transforms: Specs, MDN
Linear Gradient: Specs, MDN
SVG: Specs, MDN

Related

Creating a background-image gradient triangle that is horizontally centered

I want to create a triangle pointing down in css by using clip-path: polygon(...) and apply a gradient on it using background-image: linear-gradient(...).
This all works fine but I need this shape as the background of my web page.
It needs to always be centered and it needs to clip/cut off the left and right edges that do not fit in the browser window. The triangle should not re-scale itself; I want to preserve the steepness of the triangle's edges and the height of the triangle should not change:
As illustrated, the triangle should stay the same width and height even when the browser window is too small to contain it.
So far I have:
div.main-background {
position: absolute;
z-index: -1;
top: 0;
height: 500px;
width: 100%;
background-image: linear-gradient(to bottom, #65AAB0, #AEE2B6);
background-attachment: fixed;
background-position-x: center;
background-size: 1400px 500px;
clip-path: polygon(50% 80%, 0 0, 1400px 0);
}
<div class="main-background"></div>
but this is clearly wrong.
You can do this with SVG
html,
body {
margin: 0
}
svg {
width: 100%;
}
<svg viewBox="0 0 1920 400" height="400" preserveAspectRatio="xMidYMax slice">
<defs>
<linearGradient id="Gradient1" x1="0" x2="0" y1="0" y2="1">
<stop offset="0%" stop-color="#65AAB0"></stop>
<stop offset="100%" stop-color="#AEE2B6"></stop>
</linearGradient>
</defs>
<polygon points="0,0 960,400 1920,0" fill="url(#Gradient1)"></polygon>
</svg>
Using viewport units, is this what you want? Works on any resolution.
div.main-background {
position: absolute;
z-index: -1;
top: 0;
left: 0;
right: 0;
height: 35.71vw;
background-image: linear-gradient(to bottom, #65AAB0, #AEE2B6);
background-attachment: fixed;
background-position: center;
clip-path: polygon(50% 80%, 0 0, 100vw 0);
}
<div class="main-background"></div>
You can try multiple background like below. I made the triangle to have a width of 600px and a height of 300pxthat you can easily adjust.
body {
background:
linear-gradient(to bottom right,transparent 49.8%,#fff 50%) calc(50% + 150px) 0 /300px 300px,
linear-gradient(to bottom left, transparent 49.8%,#fff 50%) calc(50% - 150px) 0 /300px 300px,
linear-gradient(to bottom, #65AAB0, #AEE2B6)top center/ 600px 300px;
background-repeat:no-repeat;
}
Easier with CSS variable :
body {
--w:800px;
--h:300px;
background:
linear-gradient(to bottom right,transparent 49.8%,#fff 50%) calc(50% + calc(var(--w)/4)) 0 /calc(var(--w)/2) var(--h),
linear-gradient(to bottom left, transparent 49.8%,#fff 50%) calc(50% - calc(var(--w)/4)) 0 /calc(var(--w)/2) var(--h),
linear-gradient(to bottom, #65AAB0, #AEE2B6)top center/ var(--w) var(--h);
background-repeat:no-repeat;
}
You are going about it the wrong way. Your div contains no content and is thus simply decorative cruft. If you want a page background of certain appearance, then whatever appearance the background should have, goes into the background property of the document element (typically body, or html).
Get rid of your useless div.main-background which serves no purpose whatsoever, and use the following background image, either standalone (in its own SVG file) or inline using a data: URI:
<?xml version="1.0" ?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1 1">
<polygon fill="lime" points="0,0 0.5,0.4 1,0" />
</svg>
The following CSS declaration will use the above as a background image, from your explanation the background size should be a definite length (as opposed to one relative to viewport dimensions), I will use 40em because I didn't pick any clues from your question:
body {
background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1 1"><polygon fill="lime" points="0,0 0.5,0.4 1,0" /></svg>');
background-size: 40em;
background-repeat: no-repeat;
background-position: top center;
}
Alternatively, you can use a standalone SVG file, then your background rule will be different:
background: url(<URL-of-SVG-file>);
You can add the gradient easily by editing SVG content, it's a basic SVG feature, one of the other answers here even demonstrates how.
Maybe you can use that kind of trick with just CSS and an after pseudo-element:
body {
overflow: hidden;
}
.arrow-down {
--w:800px;
--h:300px;
position: relative;
width: var(--w);
height: var(--h);
margin-left: 50%;
transform: translate(-50%, 0);
background-image: linear-gradient(to bottom, #65AAB0, #AEE2B6);
}
.arrow-down::after{
content: '';
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
border: solid white;
border-width: calc(var(--h)/2) calc(var(--w)/2);
border-top-color: transparent;
}
<body>
<div class="arrow-down"></div>
</body>
Of course, you can tweak width and height to better suit your needs.

Making skewed elements on image transparent

I've tried following a guide on Youtube for help with this, and I can get it to work - sort of.
I'm trying to place two divs inside a section, where the top one is to house an image, and the bottom one be place for text etc.
The thing I'd like, is for the the top one to have a skewed razorblade dip in the middle, so the image sort of bleeds onto the bottom div.
I've managed to make the skew elements and place them where I'd like, but I when I turn them transparent, they seem to disappear.
Example: https://imgur.com/DsqNvZI
My CSS:
.section_1 {
height: 800px;
width: auto;
background: red;
}
.section_image {
height: 400px;
width: auto;
background: green;
position: relative;
background-image: url(lolsovs.jpg);
}
.section_image::after, .section_image::before {
position: absolute;
content: '';
width: 150px;
height: 150px;
background: green;
z-index: 100;
bottom: -1em;
}
.section_image::after {
left: 50%;
transform: skew(0, -20deg);
z-index: 100;
}
.section_image::before {
right: 50%;
transform: skew(0, 20deg);
}
.section_text {
background: purple;
height: 400px;
width: auto;
z-index: -100;
}
I'm still a novice when it comes to all of this stuff, so go gentle on me!
Thanks in advance!
but I when I turn them transparent, they seem to disappear.
Which is logical since you made them transparent. I advise you to consider another way to achieve this. You may simply consider some linear-gradient to color the bottom part to have this transparent part on the top:
.image {
height: 200px;
background:url(https://lorempixel.com/400/200/) center/cover no-repeat;
}
.bottom {
height:200px;
margin-top:-50px;
background:
linear-gradient(to bottom left,transparent 50%,purple 51%)calc(50% - 21px) 0/40px 50px no-repeat,
linear-gradient(to bottom right,transparent 50%,purple 51%)calc(50% + 20px) 0/40px 50px no-repeat,
linear-gradient(purple,purple)100% 0/calc(50% - 40px) 50px no-repeat,
linear-gradient(purple,purple)0 0/calc(50% - 40px) 50px no-repeat,
linear-gradient(purple,purple)0 50px/100% 100% no-repeat;
}
<div class="image">
</div>
<div class="bottom">
</div>
And for better handling you can use CSS variable to adjust dimension:
.image {
height: 200px;
background:url(https://lorempixel.com/400/200/) center/cover no-repeat;
}
.bottom {
height:200px;
margin-top:calc(-1 * var(--h,50px));
background:
linear-gradient(to bottom left,transparent 50%,purple 51%)calc(50% - (var(--w,50px) /2)) 0/var(--w,50px) var(--h,50px) no-repeat,
linear-gradient(to bottom right,transparent 50%,purple 51%)calc(50% + (var(--w,50px) /2)) 0/var(--w,50px) var(--h,50px) no-repeat,
linear-gradient(purple,purple)100% 0/calc(50% - var(--w,50px)) var(--h,50px) no-repeat,
linear-gradient(purple,purple)0 0/calc(50% - var(--w,50px)) var(--h,50px) no-repeat,
linear-gradient(purple,purple)0 var(--h,50px)/100% 100% no-repeat;
}
<div class="image">
</div>
<div class="bottom" style="--h:80px;--w:100px">
</div>

Create a diagonal background image [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I want to create a diagonal background image as seen in the attached image. I can create a diagonal line using linear-gradient however as I have two different angles this didn't work.
Using Linear Gradients:
This can be done using multiple background images and positioning them accordingly. In the snippet below I've used 3 different layers - one for the top angle (a triangle which is transparent for 50% and is colored for the rest), one for the middle which is essentially nothing but a solid colored rectangle, this is created using linear gradients as it is easier to control the dimensions of an image and finally one for the bottom angle (same approach as the top one but this has a different height and so different angle.)
The output is also responsive as you can see by hovering the element in the below snippet. In the 2nd div, I've set different colors for each image so that you can see how it is formed.
div {
height: 300px;
width: 100%;
background: linear-gradient(to bottom right, transparent 50%, lightblue 51%), linear-gradient(lightblue, lightblue), linear-gradient(to top right, transparent 50%, lightblue 51%);
background-size: 100% 30px, 100% calc(100% - 130px), 100% 100px;
background-position: top left, left 30px, bottom left;
background-repeat: no-repeat;
transition: all 1s ease; /* just for demo */
}
/* just for demo */
div {
margin-bottom: 10px;
}
div:hover {
height: 400px;
}
div:nth-of-type(2) {
background: linear-gradient(to bottom right, transparent 50%, lightblue 51%), linear-gradient(lightpink, lightpink), linear-gradient(to top right, transparent 50%, lightgreen 51%);
background-size: 100% 30px, 100% calc(100% - 130px), 100% 100px;
background-position: top left, left 30px, bottom left;
background-repeat: no-repeat;
}
<div></div>
<div></div>
Using SVG: recommended
This is the approach that I generally recommend and is the best. It involves creating the shape using SVG and then placing it absolutely behind the div element.
div {
position: relative;
height: 300px;
width: 100%;
}
svg {
position: absolute;
height: 100%;
width: 100%;
}
polygon {
fill: lightblue;
}
<div>
<svg viewBox='0 0 300 100' preserveAspectRatio='none'>
<polygon points='0,10 300,0 300,100 0,75z' />
</svg>
</div>
Using Clip-path:
Another approach that can be used is to position a pseudo-element behind the main div and then set a clip-path in the required shape to this pseudo-element.
Note: This snippet will currently work only in WebKit powered browsers. Firefox would need the clip-path to be created via SVG element whereas IE doesn't support it all.
div {
position: relative;
height: 300px;
width: 100%;
}
div:before {
position: absolute;
content: '';
height: 100%;
width: 100%;
background: lightblue;
-webkit-clip-path: polygon(0% 5%, 100% 0%, 100% 100%, 0% 75%);
clip-path: polygon(0% 5%, 100% 0%, 100% 100%, 0% 75%);
}
<div></div>
CSS Perspective
You can use a CSS Perspective Transform to create the shape you want.
div {
margin-top: 25px;
width: 500px;
height: 150px;
transform: perspective( 800px ) rotateY( -25deg );
background: blue;
}
<div></div>
CSS Tricks Docs
Perspective - CSS | MDN
You can apply perspective to the parent container of the rotated div to give it 3-dimensional depth from the front of the viewport.
N.B. For the difference between transform: perspective(value) and perspective: value, see the CSS Tricks Almanac entry on perspective:
Important: Please note the perspective property doesn't affect how the element is rendered; it simply enables a 3D-space for children
elements. This is the main difference between the transform: perspective() function and the perspective property. The first
gives element depth while the latter creates a 3D-space shared by all
its transformed children.
After applying a 3-dimensional depth to the parent container using perspective, you can then apply rotateY to the div you want to rotate.
Working Example:
section {
position: relative;
width: 600px;
perspective: 800px;
transform: translateX(-60px);
}
div:nth-of-type(1) {
position: absolute;
top:30px;
left: 0;
width: 100%;
height: 100px;
background-color: rgb(235,250,255);
transform: rotateY(320deg);
}
div:nth-of-type(2) {
position: absolute;
top: 0;
left: 220px;
width: 120px;
height: 140px;
background-color: rgb(103,201,236);
box-shadow: 6px 6px 6px rgba(127,127,127,0.5);
}
div:nth-of-type(3) {
position: absolute;
top: 24px;
left: 340px;
width: 120px;
height: 140px;
background-color: rgb(255,255,255);
box-shadow: 6px 6px 6px rgba(127,127,127,0.5);
}
<section>
<div></div>
<div></div>
<div></div>
</section>

How to accomplish this shape with angled cuts at the bottom and an image background in CSS?

I have read up on various methods and played with the Clippy tool, the problem is the browser support just isn't there yet. What would be the best method for accomplishing the look of the image below with CSS? I am trying to add a shape as bottom-border as you can see in the image below right after the blue background image. Is there a way I can do this that most recent major browsers support through CSS?
What I've tried (doesn't seem to work in Chrome and others):
.element {
-webkit-clip-path: polygon(50% 0%, 100% 0, 100% 86%, 75% 100%, 0 85%, 0 0);
clip-path: polygon(50% 0%, 100% 0, 100% 86%, 75% 100%, 0 85%, 0 0);
}
The desired result would look something like:
Both dippas' answer and the demo in misterManSam's comment are good but they would work only if the page background is a solid color (which can then be used as border's color or within the gradient). They would run into problems when the page's background is either an image (or) a gradient and they should show through the cutout portion of the shape.
For such cases I would recommend using SVG instead of CSS because it is so complex to create it with CSS that it is not actually worth the effort. Though you've asked for CSS, I will detail these SVG methods here just in case you want to use them (or atleast some future readers might find it helpful).
With SVG:
With SVG we can either create a path and fill it with the image (or) use a SVG mask for creating the shape. (Note: CSS clip-path using SVG is still a no-go due to lack of support in IE.)
Below snippet uses SVG path element to create the shape and then fill it with the image.
svg {
height: 200px;
width: 100%;
}
path {
fill: url(#image);
}
/* Just for demo */
path:hover{
cursor: pointer;
}
body {
min-height: 100vh;
background-image: radial-gradient(circle, #3F9CBA 0%, #153346 100%);
}
<svg viewBox='0 0 1024 200' preserveAspectRatio='none'>
<defs>
<pattern id='image' height='200' width='1024' patternUnits='userSpaceOnUse'>
<image xlink:href='http://lorempixel.com/1024/200/nature/3' height='200' width='1024' />
</pattern>
</defs>
<path d='M0,0 1024,0 1024,150 716.8,200 0,150z' />
</svg>
The following snippet uses SVG mask. The difference between using a path with an image fill and a mask is the hover area. With a path the hover effects are restricted to the shape boundary whereas with a mask, the image is still a rectangle (or square) and so hover effects are triggered even outside.
svg {
height: 200px;
width: 100%;
}
image {
mask: url(#masker);
}
/* Just for demo */
image:hover{
cursor: pointer;
}
body {
min-height: 100vh;
background-image: radial-gradient(circle, #3F9CBA 0%, #153346 100%);
}
<svg viewBox='0 0 1024 200' preserveAspectRatio='none'>
<defs>
<mask id='masker' x='0' y='0' width='1024' height='200'>
<polygon points='0,0 1024,0 1024,200 0,200z' fill="#fff" />
<path d='M0,150 716.8,200 1024,150 1024,200 0,200z' fill="#000" />
</mask>
</defs>
<image xlink:href='http://lorempixel.com/1024/200/nature/3' height='200' width='1024' />
</svg>
With CSS:
The below option is our best bet with pure CSS but unfortunately it has poor browser support. It uses CSS linear-gradient as mask images to hide the portions that are not required. This method works only in Webkit powered browsers for now and so is a no-go.
.shape {
height: 200px;
width: 100%;
background-image: url(http://lorempixel.com/1200/200/nature/3);
-webkit-mask-image: linear-gradient(to top right, transparent 49.5%, white 50.5%), linear-gradient(to top left, transparent 49.5%, white 50.5%), linear-gradient(white, white);
mask-image: linear-gradient(to top right, transparent 49.5%, white 50.5%), linear-gradient(to top left, transparent 49.5%, white 50.5%), linear-gradient(white, white);
-webkit-mask-size: 70.5% 30%, 30% 30%, 100% 70%;
-webkit-mask-position: bottom left, bottom right, top left;
-webkit-mask-repeat: no-repeat;
}
body {
min-height: 100vh;
background-image: radial-gradient(circle, #3F9CBA 0%, #153346 100%);
}
<div class='shape'></div>
Other attempts to produce a transparent cut run into problems if the shape has to be responsive. For example, the below snippet uses very complex transformations, positioning etc to achieve this shape but it is not responsive (view in full page mode). I wouldn't have recommended this method even if the shape was responsive (due to complexities involved) but the lack of responsiveness means this is a no-go.
.shape {
position: relative;
height: 200px;
width: 100%;
overflow: hidden;
}
.shape-left,
.shape-right,
.shape img {
position: absolute;
height: 100%;
}
.shape-left {
width: 75%;
transform: skewY(5deg);
overflow: hidden;
}
.shape-left img {
top: -7%;
bottom: 0px;
width: 133.3%;
transform: skewY(-5deg);
}
.shape-left,
.shape-left img {
transform-origin: bottom right;
backface-visibility: hidden;
}
.shape-right {
right: 0%;
width: 25%;
transform: skewY(-10deg);
overflow: hidden;
}
.shape-right img {
top: -13.5%;
left: -300%;
width: 400%;
transform: skewY(10deg);
}
.shape-right {
transform-origin: bottom left;
backface-visibility: hidden;
}
/* just for demo */
.reference {
height: 200px;
width: 100%;
}
.reference img {
height: 100%;
width: 100%;
}
* {
box-sizing: border-box;
}
body {
min-height: 100vh;
background-image:radial-gradient(circle, #3F9CBA 0%, #153346 100%);
}
<div class='shape'>
<div class='shape-left'>
<img src='http://lorempixel.com/800/200/nature/3' />
</div>
<div class='shape-right'>
<img src='http://lorempixel.com/800/200/nature/3' />
</div>
</div>
<hr>
<div class='reference'>
<img src='http://lorempixel.com/800/200/nature/3' />
</div>
Note: This may have been the item that misterManSam was referring to in comments but I feel the needs are a bit different here even though both involve creating unusual borders.
you can use a background-image on a div and two shapes using it pseudo-selectors :before/:after
Something like this:
.bg {
background: url(http://lorempixel.com/1600/900) no-repeat center top;
min-height: 100px;
min-width: 200px;
position: relative
}
.bg:before {
content: "";
border-bottom: 65px solid white;
border-right: 575px solid rgba(0, 0, 0, 0);
position: absolute;
left: 0;
bottom: 0;
}
.bg:after {
content: "";
border-bottom: 65px solid white;
border-left: 200px solid rgba(0, 0, 0, 0);
position: absolute;
right: 0;
bottom: 0;
}
<div class="bg"></div>
I think the easiest way to do it is with pseudo elements on the parent div element. This is basic CSS knowledge and can be implemented very easily. The parent div needs to have the position: relative; property set and the rest is done by the ::before and ::after elements.
.background::before {
transform: rotate(10deg);
position: absolute;
}
Example
Hope this helps.

Gradient help to create a slanted div

So I've been at it for a while trying to achieve this one shape with CSS with no good solutions. I need this to be an image because this div may resize and I want it to stay intact. I've also attempted to create an SVG which did not work out very well, I've seen some people work with gradient to make shapes but I'm not able to find any good guide to point me in the right direction. Any help is appreciated :)
Using gradients with angles is not fit for your case because (as already pointed out by King King in comments) as the width the increases, the angle of the gradient (or) the color stop percentages need to be modified to maintain the shape. That is very tricky and so this method can be employed only when the shape has fixed dimensions.
However gradients can still be used with the to [side] [side] syntax because gradients defined using this syntax can adapt to variations in container sizes. In this method no pseudo-elements are used.
$(document).ready(function() {
$('#increase').on('click', function() {
$('.gradient').css('width', '300px').css('height', '500px');
})
})
div {
display: inline-block;
vertical-align: top;
height: 300px;
width: 100px;
margin: 10px;
color: beige;
transition: all 1s;
}
.gradient {
padding: 10px;
background: linear-gradient(to top right, transparent 50%, tomato 50%) no-repeat, linear-gradient(to top right, transparent 0.1%, tomato 0.1%) no-repeat;
background-size: 100% 100px, 100% 100%;
background-position: 0% 100%, 0% -100px;
}
/* Just for demo */
body {
background: -webkit-radial-gradient(50% 50%, circle, aliceblue, steelblue);
background: radial-gradient(circle at 50% 50%, aliceblue, steelblue);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="gradient">Some content</div>
<br>
<br>
<button id="increase">Increase Width & Height</button>
Note that it is better to make sure that the text doesn't flow into the slanted section of the shape because wrapping the text around to fit within the shape is not straight-forward.
I have attempted to make that in css as per ur image. http://jsfiddle.net/3zkme/- See if this could help. Thanks.
HTML
<div style="margin:30px">
<div class="trapezoid">
</div>
</div>
CSS
.trapezoid{
top: 150px;
vertical-align: middle;
border-bottom: 120px solid red;
border-left: 200px solid transparent;
border-top-left-radius:0px;
height: 0;
width: 150px;
transform:rotate(270deg);
-ms-transform:rotate(270deg); /* IE 9 */
-webkit-transform:rotate(270deg); /* Opera, Chrome, and Safari */
}
/* ---------- */
.trapezoid {
position:relative;
}
.trapezoid:after {
content:' ';
left:-14px;
top:10px;
position:absolute;
background:red;
border-radius:0px 0 0 0;
width:164px;
height:40px;
display:block;
}
You do not use a gradient for this, you just need to use a pseudo-element like :after.
Sample code:
#bookmark {
width: 50px;
height: 100px;
position: relative;
background: red;
}
#bookmark:after {
content: "";
position: absolute;
left: 0;
bottom: 0;
width: 0;
height: 0;
border-bottom: 35px solid #FFF;
border-right: 50px solid transparent;
}
Live JSFiddle
If you want the shape to be filled in with a gradient, you can do that, too. Just add that to the CSS:
background: linear-gradient(to right, #ff0000 0%,#B00000 100%);