How to create a div with an irregular shape? - html

Is it possible to create a div with an irregular shape with CSS? I already searched but I can't find a good example. The style is something like this:
/
/ \
/ \
/ \
/___________________________\
There should be a line on the top that connects it. Basically it has different height on the left and right side.

THE SVG WAY
Since the shape you request is not possible with only CSS, I suggest you use SVG to draw the shape.
The following piece of code will create the below shape:
<svg height="150" width="150">
<polygon points="20,10 100,30 120,100 0,100" style="fill:red;" />
</svg>
SVG is a powerful tool to make shapes otherwise impossible without using images. Read up on it here.
HTML & CSS Answer
This can be done by using perspective and transform. You create two divs: one that will get the perspective and one that will be transformed. Just know that anything in the .test-div will also be transformed, so if you put text in there, it will also get transformed.
.wrapper {
width: 100px;
height: 100px;
margin-left: 100px;
perspective: 150px;
}
.test {
height: 100px;
width: 100px;
background: red;
transform: rotateX(45deg);
}
<div class="wrapper">
<div class="test"></div>
</div>
Result
JSFIDDLE

This can also be done using CSS clip-path
div {
width: 200px;
height: 150px;
background: red;
-webkit-clip-path: polygon(20% 10%, 85% 30%, 100% 100%, 0% 100%);
clip-path: polygon(20% 10%, 85% 30%, 100% 100%, 0% 100%);
}
<div></div>
You can then just change the background element if you need an image.
div {
width: 200px;
height: 150px;
background: url(https://lorempixel.com/200/150/);
-webkit-clip-path: polygon(20% 10%, 85% 30%, 100% 100%, 0% 100%);
clip-path: polygon(20% 10%, 85% 30%, 100% 100%, 0% 100%);
}
<div></div>
In their current state, clip-paths aren't as widely supported as inline or imported SVG but is a much cleaner, and in some cases, easier variant to use.
Browser Support

You can try using overflow hidden and transforms, though the best approach will be svg.
HTML
<div class="out">
<div class="in"></div>
</div>
CSS
body { background:url(http://www.placecage.com/g/640/480) }
.out {
height: 100px;
width: 150px;
transform-origin: 0% 100%;
transform: skew(-10deg);
overflow: hidden;
}
.in {
height: 110px;
width: 148px;
position: relative;
left: -43px;
top: -7px;
transform-origin: 0% 0%;
transform: skew(30deg) rotate(10deg);
background: rgba(9,40,0,0.8);
transition: 0.5s ease;
}
.in:hover {
background: rgba(50,0,70,0.7);
transition: 0.5s ease;
}
FIDDLE : https://jsfiddle.net/xb1jxd7g/

Following it for diamond and make a way around to rotate it and you'll get your shape :
#diamond-shield {
width: 0;
height: 0;
border: 50px solid transparent;
border-bottom: 20px solid red;
position: relative;
top: -50px;
}
#diamond-shield:after {
content: '';
position: absolute;
left: -50px; top: 20px;
width: 0;
height: 0;
border: 50px solid transparent;
border-top: 70px solid red;
}

Related

how to put color to div on bottom using bootstrap?

As shown in image , there is navy blue color given to div inclinedly, how can do it using bootstrap in asp.net core project?
You cannot do with bootstrap. However i have used CSS Path to create the same shape
You can use this website to make CSS Path
.backgroundCover {
height: 200px;
width: 200px;
background: blue;
border:1px solid black;
}
#clipPath {
height: 200px;
width: 200px;
background: white;
clip-path: polygon(0 0, 100% 0, 100% 50%, 75% 100%, 25% 100%, 0% 50%);
}
<div class="backgroundCover">
<div id="clipPath">
</div>
</div>
You can also use the :after and :before pseudo elements to create rectangles and then rotate them. This has higher support rate by using transform instead of clip-path in terms of old browsers.
body { background: black; }
.container {
width: 200px;
height: 260px;
background: white;
overflow: hidden;
position: relative;
}
.container:before,
.container:after {
content: '';
width: 50%;
height: 50%;
position: absolute;
background: #0d2e41;
bottom: -25%;
}
.container:before {
transform: rotateZ(135deg);
left: -25%;
}
.container:after {
transform: rotateZ(225deg);
right: -25%;
}
<div class="container">
</div>

Is there a way to specify corners in linear-gradient?

The goal is to create something like this:
.square {
width: 100px;
height: 100px;
background-image: linear-gradient(45deg, purple 50%, gray 50%);
}
<div class="square"></div>
With a square it's easy, as we know that if we make a line from the two corners in front of each other, it will close 45deg with the side next of it. But what if we don't know the width and height of the element, but we want to keep the effect? Just a logic, but maybe it helps to find the solution: the effect could be earned with a square transform(scale)-d to the required parameters, but the problem still exists: we don't know those parameters. Another logic: if the gradient would be an image, (with worse quality) with background-size, it could be stretched.
Any ideas?
Yep, there’s a syntax for corners!
.square {
width: 200px;
height: 100px;
background-image: linear-gradient(to top right, purple 50%, gray 50%);
}
<div class="square"></div>
Maybe you can try using clip-path with :after and ':before' pseudo class.
.square {
width: 100px;
height: 100px;
position: relative;
}
.rectangle {
margin-top: 1em;
width: 100px;
height: 200px;
position: relative;
}
.square:after {
content: '';
position: absolute;
width: 100%;
height: 100%;
background: grey;
clip-path: polygon(100% 100%, 0 0, 100% 0);
}
.square:before {
content: '';
position: absolute;
width: 100%;
height: 100%;
background: purple;
clip-path: polygon(100% 100%, 0 0, 0 100%);
}
<div class="square"></div>
<div class="rectangle square"></div>

html/css: how to create a hexagonal image-placeholder

This is (almost) what I want to create:
HTML
<div class="hexagon1">
<div class="hexagon-in1">
<div class="hexagon-in2">
</div>
</div>
</div>
CSS
.hexagon1 {
overflow: hidden;
visibility: hidden;
-webkit-transform: rotate(120deg);
-moz-transform: rotate(120deg);
-ms-transform: rotate(120deg);
-o-transform: rotate(120deg);
transform: rotate(120deg);
width: 400px;
height: 200px;
margin: 0 0 0 -80px;
}
.hexagon-in1 {
overflow: hidden;
width: 100%;
height: 100%;
-webkit-transform: rotate(-60deg);
-moz-transform: rotate(-60deg);
-ms-transform: rotate(-60deg);
-o-transform: rotate(-60deg);
transform: rotate(-60deg);
}
.hexagon-in2 {
width: 100%;
height: 100%;
background-repeat: no-repeat;
background-position: 50%;
background-image: url(http://placekitten.com/240/240);
visibility: visible;
-webkit-transform: rotate(-60deg);
-moz-transform: rotate(-60deg);
-ms-transform: rotate(-60deg);
-o-transform: rotate(-60deg);
transform: rotate(-60deg);
}
The problem is, that I need a border on the hexagon and if possible I would like to place the picture inside an img-tag. I tried adding the border on either div but I only got a border on top and bottom of the hexagon because of the visibility-hidden or the overflow-hidden attribute.
This is what I've found so far while googling:
http://csshexagon.com/
https://www.queness.com/post/13901/create-beautiful-hexagon-shapes-with-pure-css3
https://github.com/web-tiki/responsive-grid-of-hexagons
I've also found some questions concerning this matter here on Stackoverflow but neither of them explained how exactly you could create a hexagon. Also the hexagons in the examples are all standing on an edge, which is not what I want (as demonstrated in the code). I only need one hexagon and not a grid as well.
When I tried to change the styles of the examples it always ended in a desastrous chaos. This is why I would like to know how to create and to calculate the divs which are used to create a hexagon with border and a picture inside.
Which rate does the width have to the height?
How can I create a border that has the same width on each side?
Where do I have to place the picture as background-image?
How big should the picture be (in percentage to the divs)?
What transformations do you really need to create the hexagon? (I saw an example which used scale, rotate and translate to get a picture inside)
How can the rotation be calculated?
How do I calculate the margin needed?
As I am quite the novice in web-designing can someone explain this as simple as possible? It would suffice if someone can show me according to the example-code above how the numbers are calculated. I know that a hexagon has an inner angle of 120° and that's about it.
Thanks for your help in anticipation. :)
EDIT
Another page I found about hexagons but only to create the shape and not really putting either an image in it nor having a border around it:
http://jtauber.github.io/articles/css-hexagon.html
I will refer you to go with SVG approach to create this shape. Its really easy and also if you are considering a responsive web layout it can be achieved with this easily.
Reason for this approach -
1. You donot have to write much css.
2. Inline SVG is the modern web approach .
3. Scalable and durable.
4. Responsive
The polygon tag in the svg makes the shape that you want and with the css we can target the things we want to achieve like border in this case. Image has been linked using pattern.
Below is the snippet with example of what you need.
svg {
width: 30%;
margin: 0 auto;
}
#hex {
stroke-width: 2;
stroke: red;
}
<svg viewbox="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
<pattern id="img" patternUnits="userSpaceOnUse" width="100" height="100">
<image xlink:href="https://dummyimage.com/600x400/red/fff" x="-25" width="150" height="100" />
</pattern>
</defs>
<polygon id="hex" points="50 1 95 25 95 75 50 99 5 75 5 25" fill="url(#img)"/>
</svg>
<svg viewbox="0 0 200 200" version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
<pattern id="img" patternUnits="userSpaceOnUse" width="100" height="100">
<image xlink:href="https://farm4.staticflickr.com/3165/5733278274_2626612c70.jpg" x="-40" width="150" height="100" />
</pattern>
</defs>
<polygon id="hex" points="25 8 75 8 100 50 75 92 25 92 0 50" fill="url(#img)" />
</svg>
Important Note
Be informed that this solution does not work for those who want to create something similar supported by all browsers as for the time being IE does not support the clip-path-property used in this example!!
I've found a way to do it thanks to #SahilDhir although it's more of a workaround:
HTML
<div class="poligon">
<img src="http://lorempixel.com/g/600/400/">
</div>
CSS
.poligon {
display: inline-block;
position: relative;
width: 200px;
height: 180px;
background: red;
box-sizing: border-box;
-webkit-clip-path: polygon(0% 50%, 25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%);
-moz-clip-path: polygon(0% 50%, 25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%);
}
.poligon img {
position: absolute;
top: 2px; /* equal to border thickness */
left: 2px; /* equal to border thickness */
width: 196px; /* container height - (border thickness * 2) */
height: 176px; /* container height - (border thickness * 2) */
-webkit-clip-path: polygon(0% 50%, 25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%);
-moz-clip-path: polygon(0% 50%, 25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%);
}
Note that I did not calculate much here, but rather tried achieving a six-sided figure.
I will have the problem that my picture will have a transparent background, but I thought that I might produce a linear gradient to fill the background polygon. I will have to try that out first though ^^
I will not mark this as the final answer as my questions have not yet been answered truly. I still want to be able to create a hexagon as the one in the example I gave above where I would be able to adapt the heights and widths as well as the border thicknesses the way I want.
EDIT
As I did not find a better solution I have improved the one here and figured out the calculations needed:
HTML
<div class="poligon">
<div class="hex-background">
<img src="https://img.clipartfest.com/953d8641fe933437bbc41d48e6fc8492_yellow20stars20clipart-christmas-stars-clipart-without-background_532-506.png">
</div>
</div>
CSS
.poligon {
display: inline-block;
position: relative;
width: 120px;
height: 103.92px; /* width * 0.866 */
background: red;
box-sizing: border-box;
-webkit-clip-path: polygon(0% 50%, 25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%);
-moz-clip-path: polygon(0% 50%, 25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%);
}
.hex-background {
position: absolute;
background-color: white;
top: 2px; /* equal to border thickness */
left: 2px; /* equal to border thickness */
width: 116px; /* container width - (border thickness * 2) */
height: 99.92px; /* container height - (border thickness * 2) */
-webkit-clip-path: polygon(0% 50%, 25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%);
-moz-clip-path: polygon(0% 50%, 25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%);
}
.poligon img {
position: absolute;
width: 116px; /* container width - (border thickness * 2) */
height: 99.92px; /* container height - (border thickness * 2) */
-webkit-clip-path: polygon(0% 50%, 25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%);
-moz-clip-path: polygon(0% 50%, 25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%);
}
The clip-path part is correct if you want a same-sided hexagon.
With the picture above you can see how I found those numbers ;) If you have further questions about this, don't hesitate to ask. I'll try to explain it the best I can.
I needed something similar, and the easiest way to do it is with two hexagons, one on top of the other.
Using the shapes provided by The Shapes of CSS:
#hexagon1 {
width: 100px;
height: 55px;
background: red;
position: absolute;
z-index: 2;
}
#hexagon1:before {
content: "";
position: absolute;
top: -25px;
left: 0;
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 25px solid red;
}
#hexagon1:after {
content: "";
position: absolute;
bottom: -25px;
left: 0;
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-top: 25px solid red;
}
#hexagon2 {
width: 101px;
height: 56px;
background: black;
position: relative;
z-index: 1;
}
#hexagon2:before {
content: "";
position: absolute;
top: -26px;
left: 0;
width: 0;
height: 0;
border-left: 51px solid transparent;
border-right: 51px solid transparent;
border-bottom: 26px solid black;
}
#hexagon2:after {
content: "";
position: absolute;
bottom: -26px;
left: 0;
width: 0;
height: 0;
border-left: 51px solid transparent;
border-right: 51px solid transparent;
border-top: 26px solid black;
}
Here's a CodePen I made for you: http://codepen.io/vogelbeere/pen/peYjNe

CSS: Colored div with transparent box [duplicate]

This question already has answers here:
turning a div into transparent to see through two containers
(4 answers)
Closed 6 years ago.
Is there any way to have a div with a background-color that takes up 100% width and a transparent box inside it that shows the original background?
Solution 1: Clip-path
Clip path can be quite useful, as it keeps the code clean and simple. However, it does not have great support (yet) in browsers, and should hence only be used in test environments.
html {
background: url("http://butlers-web.co.uk/Content/Images/BWLOGO.png") 100% 100%;
}
div {
height: 300px;
width: 100%;
background: tomato;
position: relative;
-webkit-clip-path: polygon(0% 0%, 0% 100%, 100% 100%, 100% 0, 50% 0, 50% 20%, 80% 20%, 80% 80%, 20% 80%, 20% 20%, 50% 20%, 50% 0);
}
<div>
</div>
Solution 2: Box shadow Trick
The box shadow trick uses a pseudo element and overflow:hidden; to create the box shadow/colouring of the element.
html {
background: url("http://butlers-web.co.uk/Content/Images/BWLOGO.png") 100% 100%;
}
div {
height: 300px;
width: 100%;
overflow:hidden;
position: relative;
}
div:before{
content:"";
position:absolute;
top:20%;width:60%;height:60%;left:20%;
box-shadow:0 0 0 999px tomato;
}
<div></div>
Solution 3: Gradients
You could use multiple gradient background, however this may or may not be suitable as gradients don't always turn out rendered very nicely:
html {
background: url("http://butlers-web.co.uk/Content/Images/BWLOGO.png") 100% 100%;
}
div {
position: relative;
height: 300px;
width: 100%;
background: linear-gradient(tomato, tomato), linear-gradient(tomato, tomato), linear-gradient(tomato, tomato), linear-gradient(tomato, tomato);
background-size: 100% 20%, 20% 100%, 100% 20%, 20% 100%;
background-position: left bottom, right bottom, left top, left top;
background-repeat: no-repeat;
}
<div></div>
Solution 4: Borders
Whilst this may or may not be suitable for you, there is still a chance that it may help, so will post here anyway:
html {
background: url("http://butlers-web.co.uk/Content/Images/BWLOGO.png") 100% 100%;
}
div {
position: relative;
height: 300px;
width: 100%;
box-sizing: border-box;
border-left: 20vw solid tomato;
border-right: 20vw solid tomato;
border-top: 50px solid tomato;
border-bottom: 50px solid tomato;
}
<div></div>
Solution 5: Background attachment
I have recently come across the background-attachment property, so am still coming to grips with it. However, if you wished the background to appear behind you may be able to alter the below snippet to your needs:
body {
background: url('http://butlers-web.co.uk/Content/Images/BWLOGO.png');
background-attachment: fixed;
}
.wrapper {
width: 100%;
height: 300px;
background: tomato;
position: relative;
}
.inner {
width: 80%;
height: 80%;
background: url('http://butlers-web.co.uk/Content/Images/BWLOGO.png');
background-attachment: fixed;
position: absolute;
top: 10%;
left: 10%;
box-sizing:border-box;
border:2px solid black;
}
<div class="wrapper">
<div class="inner"></div>
</div>
You're going to need two div for that. A parent, with the red background, then the inner div.
give the inner div margin: 10px auto; as a start.

Implement a rectangle shape with a transparent triangular cut at bottom

I want to create a non-rectangular image with CSS3, I think implement something like below image
It is a square with a transparent triangle gap in bottom of it, I know I can implement it with some trick, as example with png image but I want create this with HTML element not with image,
any body know how can I do that? Is that implementable with HTML and CSS?
<----------------------------------------------- clip-path solution ------------------------------------------------->
You could use clip-path to do this:
dabblet
.rect {
position: absolute;
width: 165px;
height: 100px;
background-color: black;
-webkit-clip-path: polygon(0 0, 0 100%, 40% 100%, 50% 75%, 60% 100%, 100% 100%, 100% 0%);
}
body {
background-color: lightblue;
}
Note: Firefox does not support this property.
Works fine on Chrome.
Check out the browser support for clip-path ----------> HERE.
<------------------------- <svg> solution - will support all browsers [except IE8] ------------------------->
Since, Firefox still supports clip-path: url(), you can create an inline svg element with a polygon element inside clipPath that defines the points. Give the clipPath element an id(#mask) and use it in CSS instead of polygon(0 0, 0 100%, 40% 100%, 50% 75%, 60% 100%, 100% 100%, 100% 0%);.
dabblet
HTML:
<div class="rect"></div>
<svg>
<defs>
<clipPath id="mask">
<polygon points="0,0 0,100 66,100 82.5,75 99,100 165,100 165,0 " />
</clipPath>
</defs>
</svg>
CSS:
.rect {
position: absolute;
width: 165px;
height: 100px;
background-color: black;
-webkit-clip-path: url(#mask);
clip-path: url(#mask);
}
body {
background-color: lightblue;
}
<---------------------------------------- <svg> solution without any CSS ---------------------------------------->
dabblet
HTML:
<svg>
<polygon points="0,0 0,100 66,100 82.5,75 99,100 165,100 165,0" style="fill:black" />
</svg>
Check out browsers that supports svg ----------> HERE
A simple approach
Use box-shadow on pseudoelement, and use overflow: hidden; on main element.
div {
height: 150px;
width: 200px;
position: relative;
overflow: hidden;
}
div:before{
position: absolute;
top: 100px;
left: 67px;
content: "";
height: 50px;
width: 50px;
background: transparent;
transform-origin:0% 100%;
transform: rotate(52deg) skewX(10deg);
-webkit-transform: rotate(52deg) skewX(10deg);
box-shadow: 0 0 0 200px black;
}
<div></div>
One way to produce this transparent cut at the bottom is to use a couple of skewed pseudo-elements and position them such that they leave a triangle shaped gap at the bottom. Below is a sample snippet demonstrating this approach.
body {
background: url("http://lorempixel.com/200/400");
}
.shape {
height: 200px;
width: 200px;
overflow: hidden;
position: relative;
}
.shape:before {
height: 100%;
width: 100%;
position: absolute;
content: '';
background: black;
left: 0px;
top: 0px;
-webkit-transform: skew(-30deg);
-moz-transform: skew(-30deg);
transform: skew(-30deg);
-webkit-transform-origin: 25% -25%;
-moz-transform-origin: 25% -25%;
transform-origin: 25% -25%;
}
.shape:after {
height: 100%;
width: 100%;
position: absolute;
content: '';
right: 0px;
top: 0px;
background: black;
-webkit-transform: skew(30deg);
-moz-transform: skew(30deg);
transform: skew(30deg);
-webkit-transform-origin: 25% -25%;
-moz-transform-origin: 25% -25%;
transform-origin: 25% -25%;
}
<div class="shape"></div>
Note: This below snippet is only to show that achieving a shape with transparent cut is possible by using overlapping gradient backgrounds. However, my advice would be to not use this approach as much as possible because gradients produce jagged corners a lot of the times.
You can use two overlapping linear-gradient backgrounds on a div to achieve this effect. The angles of the triangle can be modified by modifying the gradient's angles. This is tested and found to be working fine in Mozilla FireFox, Chrome, Safari and Opera.
body {
background: url("http://lorempixel.com/200/400");
}
.shape {
height: 200px;
width: 400px;
background: -webkit-linear-gradient(-10deg, black 50%, transparent 50%), -webkit-linear-gradient(10deg, transparent 50%, black 50%);
background: -moz-linear-gradient(-10deg, black 50%, transparent 50%), -moz-linear-gradient(10deg, transparent 50%, black 50%);
background: linear-gradient(100deg, black 50%, transparent 50%), linear-gradient(-100deg, black 50%, transparent 50%);
}
<div class="shape"></div>
One potential drawback of this approach is that the edges aren't really sharp in Chrome (atleast in older versions of Chrome) whereas it is sharp in the others.