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%);
Related
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>
Alright, here is the thing. This is what I'm trying to accomplish, which I did so far:
The problem is I use hardcoded pixels right now, but it really needs to be more responsive. So it needs a height of 100% (not 200px like now). And the total width of the diagonal and content containers needs to be 50%, like the image above (so not hardcoded 100px like now). The main problem seems to be the diagonal, cause it almost seems I can only use pixels and not percentages. So if the content block gets more content, it will expand, but the diagonal will not, which is a problem.
It looks like a position absolute could fix it, but then I can't really place the content and diagonal blocks next to each other anymore. Now I gave them two different colors to be clear, but in the live example they need to look like one shape with the same background color.
.shape {
width:400px;
margin:0 auto;
display: block;
height: 200px;
position: relative;
background-image: url('https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcSQdX7yx0pVXUlaNF7WkbSJpZp5r0TflV3WdsojKKK1Xon_1hh08l4OL1yd');
}
.diagonal {
height:0;
border-width: 0px 0 200px 100px;
border-style:solid;
border-color: transparent transparent transparent #d71f55 ;
float: left;
}
.content {
height: 100%;
width: 100px;
background-color: #888;
float: left;
color: #fff;
}
<div class="shape">
<div class="content">
Content goes here
Like this
</div>
<div class="diagonal"></div>
</div>
EDIT:
By the way, I already tried using two backgrounds as well, like:
background-color: #f87f73;
background-image: -webkit-linear-gradient( -28deg, #f87f73 0%, #f87f73 60%, #292423 60%, #292423 60%);
background-image: linear-gradient( -28deg, #f87f73 0%, #f87f73 60%, #292423 60%, #292423 60%);
But that really got ugly. Too pixelated.
Edit 2:
Browser which needs to be supported:
OS: windows 8/10 :
** browsers: Chrome 47/48
** Firefox 43/44
** Internet Explorer 11
OS: mac OSX 10.9/10.10
** Chrome 47/48
** Firefox 43/44
** Safari 8/9
OS: android 5/6
** Chrome latest version
OS: iOS 8/9
** Safari latest version
You can use viewport related units for the border as described in Shape with a slanted side (responsive). This will allow you to make the shape 50% width and 100% height of the viewport and responsive:
* {
margin: 0;
padding: 0;
}
.shape {
width: 100%;
margin: 0 auto;
display: block;
height: 100vh;
position: relative;
background-image: url('https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcSQdX7yx0pVXUlaNF7WkbSJpZp5r0TflV3WdsojKKK1Xon_1hh08l4OL1yd');
}
.diagonal {
height: 0;
border-width: 0 0 100vh 25vw;
border-style: solid;
border-color: transparent transparent transparent #d71f55;
float: left;
}
.content {
height: 100vh;
width: 25vw;
background-color: #888;
float: left;
color: #fff;
}
<div class="shape">
<div class="content">
Content goes here Like this
</div>
<div class="diagonal"></div>
</div>
Viewport related units (vh and vw) have good browser support. For more info, see canIuse
This is probably how I would approach it. Using a hard 50/50 gradient rather than a border makes it pretty trivial. It seems to render ok in chrome but I haven't checked other browsers. If you want this inside a container remember to set the container to position: relative
.shape {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: auto;
height: auto;
display: block;
background-image: url('https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcSQdX7yx0pVXUlaNF7WkbSJpZp5r0TflV3WdsojKKK1Xon_1hh08l4OL1yd');
}
.content {
height: 100%;
width: 25%;
background-color: #888;
color: #fff;
float: left;
}
.diagonal {
height: 100%;
width: 25%;
background: linear-gradient(to bottom right, #888 50%, transparent 50%);
float: left;
border: none;
}
<div class="shape">
<div class="content">
Content goes here Like this
</div>
<div class="diagonal"></div>
</div>
I would like to know if it is possible to create a background like this in CSS3.
The background should span a header div and the gradient should go from white to black independent of the screen width (always white on the left side and black on the right side).
Reason for not using the image is that it takes longer to load and that I can't get it to resize it's width when making the browser smaller than 1920px (the width of the image).
Have tried linear-gradient but I can't get it to work...
Regards,
Jens
If you also want the black bar at the top you should give dimensions to the background, stop the repeating and also position it where you want (treat it like a normal background image)
div {
background-color: black;
background-image: linear-gradient(to right, white, black);
background-repeat:no-repeat;
background-size:100% 20px; /*full width, 20px height*/
background-position:0 100%; /*gradient at bottom*/
/*just to give size to demo*/
min-height:50px;
}
<div></div>
Here's some CSS for you:
#grad {
background: gray; /* For browsers that do not support gradients */
background: -webkit-linear-gradient(left, white , black); /* For Safari 5.1 to 6.0 */
background: -o-linear-gradient(right, white, black); /* For Opera 11.1 to 12.0 */
background: -moz-linear-gradient(right, white, black); /* For Firefox 3.6 to 15 */
background: linear-gradient(to right, white , black); /* Standard syntax */
}
Source: http://www.w3schools.com/css/css3_gradients.asp
I know the OP's question was answered. But I'll comment here anyway to deliver some more information to create a really more "complex" background.
First is you really can create multiple backgrounds stack on each other:
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Backgrounds_and_Borders/Using_multiple_backgrounds
Second is you can determine position, size, etc,... of a background-image. And here the concise syntax for it: https://www.w3schools.com/cssref/css3_pr_background.asp.
Why background-image? A basic (and important) theory of background in CSS is: A background of an element can have only 1 background-color, and multiple background-images sit on top of it (even if the background-color is declared after background-image, background-color will be still placed below the background-images), and you can resize, reposition those background-images. And an important thing is linear-gradient is count as a background-image, not background-color. The 2 links above do give all detailed information about it.
Here is a quick demo on a "more complex" background from the OP question using only 1 div HTML:
div {
background:
linear-gradient(to right, white, black) 0 100%/100% 20px no-repeat,
linear-gradient(to left, white, black) 0 0/100% 20px no-repeat,
black;
height: 100px;
}
<div></div>
I'm inspired writing this long comment because from a tutorial
https://levelup.gitconnected.com/how-to-implement-netflix-slider-with-react-and-hooks-bdb9b99d1ce4, there's a section from it there're verbose hacks in HTML and CSS to achieve what I'm able to do within just a single line of CSS background, and I think it's cool to share, isn't it?
/* simpler */
.box {
width: 100%;
height: 100px;
background: linear-gradient(to right,black 0%,black 30%,transparent 75%,transparent 100%), green;
}
/* more complex */
.content {
height: 100px;
position: relative;
}
.background {
display: flex;
height: 100%;
}
.left {
background: black;
width: 30%;
position: relative;
}
.left:before {
content: '';
position: absolute;
background-image: linear-gradient(to right,#000,transparent);
top: 0;
bottom: 0;
left: 100%;
width: 275px;
}
.right {
background: green;
width: 70%;
}
.content-container {
color: white;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
padding: 30px
}
<!-- simpler -->
<div class="box">
<div class="content-container">content here...</div>
</div>
<hr>
<!-- more complex -->
<div class="content">
<div class="background">
<div class="left">left</div>
<div class="right">right</div>
</div>
<div class="content-container">content here...</div>
</div>
I am trying to add left padding to a border bottom line for a div. How can I achieve this?
This is what i tried
When I add padding left then both text and border bottom line moves.
<div class='ot'>
Black border bottom should start from 30px left <div>
.ot{
width:100%;
background-color:yellow;
border-bottom: solid;
}
You could fudge it with some pseudo content.
http://jsfiddle.net/E7fFL/3/
div {
width:100%;
background-color:yellow;
border-bottom: solid 2px;
position: relative;
}
div:after {
position: absolute;
bottom: -2px;
left: 0;
width: 30px;
height: 2px;
content: '.';
background: yellow;
text-indent: -999px;
}
This will work provided the height and bottom properties are the equivalent and inverse equivalent, respectively, of the border width.
You may use a background-image and background-size. DEMO (with linear gradient)
.ot {
width:100%;
background:yellow linear-gradient(to top, black, black) no-repeat 30px bottom;
background-size: 100% 3px;
}
Or a 1 pixel image : DEMO
.ot {
width:100%;
background:yellow url(http://dummyimage.com/1x1) no-repeat 30px bottom;
background-size: 100% 3px;
}
Note , a padding:bottom average fake border heifgt might be necessary
given a div that is 500px wide, is there a way to fill the background with 2 different colors using css? I know it can be done with a background image, but just wondering if it can be done with bg color.
eg :
You can't set multiple background colors, but you could set something like:
div.twocolorish {
background-color: green;
border-left: 20px solid red;
}
As long as you don't need text to go over the part in red then this would take care of you in one div.
I ended up with this solution using linear gradients:
.dualcol-test {
background: linear-gradient(to right, green 0%, green 80%, red 80%, red 100%);
}
<div class="dualcol-test"> This div has a green and red background <br><br><br> </div>
You can achieve 2 colors in 1 div by using pseudo-element :before
HTML:
<div class="twocolordiv"></div>
CSS:
.twocolordiv {
position: relative;
z-index: 9;
background: green;
width:500px;
height:100px;
}
.twocolordiv:before {
content: "";
position: absolute;
z-index: -1;
top: 0;
right: 20%;
bottom: 0;
left: 0;
background: red;
}
You can use linear-gradient background to do this
background: linear-gradient(90deg, green 50%,red 50%);
No, you can only set one background-color. However, you could split your container into two and set a different backgorund-color for each one.
This question got me thinking about how CSS3 would approach this problem.. and frankly the specification has me confused. That said, a couple of features that are creeping through the cracks: background-size and linear-gradient.
<style type="text/css">
#ji { width: 500px; height: 300px;
background:
-moz-linear-gradient(green, green) 0px 0px no-repeat,
-moz-linear-gradient(red, red) 200px 50px no-repeat,
-moz-linear-gradient(blue, blue) 0px 250px no-repeat,
-moz-linear-gradient(gray, gray) 300px 125px no-repeat;
-moz-background-size: 450px 50px, 50px 200px, 250px 250px, 50px 250px;
}
</style>
<div id="ji">
</div>
Give this a go :)
I'm sure there are better approaches to this problem, but it does demonstrate that we'll be afforded greater flexibility with CSS backgrounds (one day).
Edit: Forgot to mention that this will only work in Firefox, though there are Webkit equivalents for linear-gradient and background size
Using the :before css attribute allows you to 'fill' a div with the two colours.
.myDiv {
position: relative; /*Parent MUST be relative*/
z-index: 9;
background: green;
/*Set width/height of the div in 'parent'*/
width: 100px;
height: 100px;
}
.myDiv:before {
content: "";
position: absolute; /*set 'child' to be absolute*/
z-index: -1; /*Make this lower so text appears in front*/
/*You can choose to align it left, right, top or bottom here*/
top: 0;
right: 0;
bottom: 60%;
left: 0;
background: red;
}
<div class="myDiv">this is my div with multiple colours. It work's with text too!</div>
An easily edited sample can be seen LIVE DEMO
Using background-image / repeat-y is the easiest solution - however, maybe you want to change colours or widths or something with Javascript.
Here's a way to do this which allows text everywhere.
http://jsfiddle.net/WQ8CG/
HTML:
<div id="container"><div class="offset">text</div></div>
CSS:
#container {
background: #ccc;
border-right: 40px solid #aaa
}
.offset {
margin-right: -40px;
zoom: 1; /* to fix IE7 and IE6 */
position: relative /* to fix IE6 */
}
Better late then never. Thought this might help:
The htmls
<div id="content">
<div id="left"></div>
<div id="right"></div>
</div>
The csss
#content { background-color: #F1EBD9; }
#left { float: left; width: 14em; }
#right { margin-left: 14em; background-color: #FFF; }
You can view this # http://alexandergutierrez.info/stretch-background-color-in-a-two-col-layout
You could you inset box shadow, and change the shadow to whatever colour you required.
CSS
-moz-box-shadow: inset 50px 0px 0px 0px rgba(156, 244, 255, 1);
-webkit-box-shadow: inset 50px 0px 0px 0px rgba(156, 244, 255, 1);
box-shadow: inset 50px 0px 0px 0px rgba(156, 244, 255, 1);