How can i create a hexagon shape with an image inside? [duplicate] - html

This question already has answers here:
html/css hexagon with image inside
(7 answers)
Closed 6 years ago.
I'm trying to create a hexagon shape with an image inside
i dont want to put the background inside the css, i want to do it using html
how can i do that?
http://jsfiddle.net/093hv8d1/
HTML
<div class="hexagon"><img src="http://www.edinphoto.org.uk/0_STREET/0_street_views_-_arden_street_2006_barry_nelson.jpg" width="200" height="200" /></div>
CSS
.hexagon {
position: relative;
width: 150px;
height: 86.60px;
background-color: #64C7CC;
margin: 43.30px 0;
float:left;
margin-right:10px;
}
.hexagon:before,
.hexagon:after {
content: "";
position: absolute;
width: 0;
border-left: 75px solid transparent;
border-right: 75px solid transparent;
}
.hexagon:before {
bottom: 100%;
border-bottom: 43.30px solid #64C7CC;
}
.hexagon:after {
top: 100%;
width: 0;
border-top: 43.30px solid #64C7CC;
}

You need to increase the border thickness ----> border-left: 103px solid transparent; and border-right: 100px solid transparent; and do some positioning adjustments. For displaying a specific region of an image, you can use clip
property. For this to work you have to use position: absolute;
How clip works?
It creates a rectangular region that reveals part of an element.
Values:
clip: rect(top offset, visible width, visible height, left offset)
The first number indicates the top offset - the top edge of the clipping window.
The last number indicates the left offset - the left edge of the clipping window.
The second number is the width of the clipping window plus the left offset(last number).
The third number is the height of the clipping window plus the top offset(first number).
Demo on dabblet
.hexagon {
position: relative;
top: 50px;
width: 150px;
height: 86.60px;
margin: 43.30px 0;
float:left;
margin-right:10px;
}
img {
position: absolute;
clip: rect(43px,200px,157px,0px);
}
.hexagon:before, .hexagon:after {
content:"";
position: absolute;
border-left: 101px solid transparent;
border-right: 100px solid transparent;
}
.hexagon:before {
top: 0px;
border-bottom: 43.30px solid #64C7CC;
}
.hexagon:after {
top: 100%;
top: 157px;
border-top: 43.30px solid #64C7CC;
}
#hexagons-1 {
display: table;
margin: 0 auto;
margin-top: 100px;
}
#hexagons-2 {
display: table;
margin: 0 auto;
margin-top:-28px;
}

Another way to do this is with clip-path. it will allow you to cover the whole hexagon, and not just the square in the middle.
JsFiddle
html:
<div class="hexagon"><img src="http://www.edinphoto.org.uk/0_STREET/0_street_views_-_arden_street_2006_barry_nelson.jpg" width="200" height="200" /></div>
css:
.hexagon{
width: 190px;
-webkit-clip-path: polygon( 50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25% );
clip-path: polygon( 50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25% );
}

Related

How do I make a slash in a webpage with HTML/CSS?

I'm trying to produce a parallelogram/slash look in my webpage as follows:
It's easy to smash two divs together and then you have a rectangle next to a rectangle, but this slash is mind boggling. Is this possible with pure CSS or HTML? The examples I've seen all use SVGs.
html,
body {
min-height: 100%; /* demo only */
}
#page {
min-height: 100vh; /* demo only */
}
#page:before {
content: '';
position: absolute;
width: 25%;
height: 150%;
left: -10%;
top: -25%;
background: #F6990D;
transform: rotate(4deg);
border-right: 4px solid #FEBF78;
}
<div id="page"></div>
Just adding the linear option, but getting around the aliasing jagged edges will be tough regardless of the approach you take.
div {
position: absolute;
top: 0;right: 0;bottom: 0; left:0;
background: rgba(255,163,3,1);
background: linear-gradient(95deg, rgba(255,163,3,1) 0%,
rgba(255,163,3,1) 9%,
rgba(245,205,135,1) 9%,
rgba(245,205,135,1) 10%,
rgba(255,255,255,1) 10%,
rgba(255,255,255,1) 100%
);
}
<div></div>
Start from a square div with four thick borders.
div {
width: 50px;
height: 50px;
border-left: 50px solid green;
border-top: 50px solid red;
border-right: 50px solid blue;
border-bottom: 50px solid yellow;
}
<div> </div>
Now reduce the square to zero height.
div {
width: 50px;
height: 0;
border-left: 50px solid green;
border-top: 50px solid red;
border-right: 50px solid blue;
border-bottom: 50px solid yellow;
}
<div> </div>
Now take off the left and bottom borders.
div {
width: 50px;
height: 0;
border-top: 50px solid red;
border-right: 50px solid blue;
}
<div> </div>
Finally, shrink the right border and make it transparent.
div {
width: 50px;
height: 0;
border-top: 50px solid red;
border-right: 15px solid transparent;
}
<div> </div>
You can adjust the numbers and add a shadow to make it look more like the example image. You can also add transform: rotate(360deg) to get cleaner aliasing in certain scenarios (this is a hack; it tricks the browser into switching to GPU-accelerated rendering mode if such a mode is available).
div {
width: 50px;
height: 0;
border-top: 300px solid orange;
border-right: 15px solid transparent;
filter: drop-shadow(10px 0 yellow);
/* HACK: trick the browser into GPU-accelerated mode if possible,
* this can help get cleaner aliasing in certain scenarios. */
transform: rotate(360deg);
}
<div> </div>
#slash {
width: 15px;
height: 100px;
transform: skew(-20deg);
background: red;
}
#container {
padding-left: 20px;
}
<div id="container">
<div id="slash">
</div>
</div>
Just create a square and use skew transform

Creating a triangle with only CSS

I'm developing a responsive web application, and need to create 2 separate content areas as follows,
So far, I tried,
border-right: 30px solid transparent;
border-bottom: 30px solid #4c4c4c;
height: 100%;
width: 100%;
position: fixed;
But, unfortunately couldn't create a triangle.
Is there any other way to create a triangle using CSS with the possibility to wrap content entirely within the div's besides using the border property?
Any help would be greatly appreciated.
I believe you are looking for triangles with borders and a transparent cut in between (which none of the existing answers seem to address) and so here is an example. It's absolutely possible to achieve with but takes a lot of hacking around.
Using CSS Transforms:
The below snippet uses pseudo-elements and transforms to produce the triangles effect. The output is responsive but the usage of skew transforms mean that if the container's shape becomes a rectangle then the skew angles would need modification and more tweaking of the positioning attributes etc.
.container {
position: relative;
overflow: hidden;
height: 200px;
width: 200px;
}
.div-1,
.div-2 {
position: absolute;
top: 0px;
left: 0px;
height: 100%;
width: 100%;
overflow: hidden;
}
.div-1 {
top: calc(-100% - 5px);
transform: skewY(45deg);
transform-origin: left top;
border-bottom: 2px solid;
}
.div-1:after {
position: absolute;
content: '';
height: calc(100% - 2px);
width: calc(100% - 2px);
top: calc(100% + 7px);
left: 0px;
transform: skewY(-45deg);
transform-origin: left top;
border: 1px solid;
}
.div-2 {
top: 5px;
transform: skewY(45deg);
transform-origin: left bottom;
border-top: 1px solid;
}
.div-2:after {
position: absolute;
content: '';
height: calc(100% - 7px);
width: calc(100% - 7px);
top: 0px;
left: 0px;
transform: skewY(-45deg);
transform-origin: left bottom;
border: 1px solid;
}
* {
box-sizing: border-box;
}
/* just for demo */
.container{
transition: all 1s;
}
.container:hover{
width: 400px;
height: 400px;
}
body{
background: radial-gradient(circle at center, aliceblue, mediumslateblue);
min-height: 100vh;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class='container'>
<div class='div-1'></div>
<div class='div-2'></div>
</div>
Using Gradients:
Another approach would be to use a couple of linear gradients as background images like in the below snippet. But there are plenty of drawbacks here too. (1) Gradients have very poor browser support at present. (2) Angular gradients tend to produce jagged lines which would need smoothing. (3) You had specifically mentioned 2 div elements in the image in question and I presume you want content within them, in which case that would need extra work.
.container {
position: relative;
overflow: hidden;
height: 200px;
width: 300px;
background: linear-gradient(to top right, transparent calc(50% + 2px), black calc(50% + 2px), black calc(50% + 4px), transparent calc(50% + 4px)), linear-gradient(to bottom left, transparent calc(50% + 2px), black calc(50% + 2px), black calc(50% + 4px), transparent calc(50% + 4px)) ;
}
.container:before{
position: absolute;
content: '';
height: calc(100% - 6px);
width: calc(100% - 6px);
left: 4px;
border-top: 2px solid black;
border-right: 2px solid black;
}
.container:after{
position: absolute;
content: '';
height: calc(100% - 6px);
width: calc(100% - 6px);
top: 4px;
border-left: 2px solid black;
border-bottom: 2px solid black;
}
/* just for demo */
.container{
transition: all 1s;
}
.container:hover{
width: 700px;
height: 400px;
}
body{
background: radial-gradient(circle at center, aliceblue, mediumslateblue);
min-height: 100vh;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class='container'>
</div>
Using SVG:
All these lead me to my suggestion, which is, to use SVG for creating such shapes. They are easy to create using just path elements, easily maintainable and are responsive by nature.
.container {
position: relative;
height: 300px;
width: 200px;
}
svg {
position: absolute;
top: 0px;
left: 0px;
height: 100%;
width: 100%;
}
svg path {
fill: transparent;
stroke: black;
}
/* just for demo */
.container {
transition: all 1s;
}
.container:hover {
height: 400px;
width: 700px;
}
body {
background: radial-gradient(circle at center, aliceblue, mediumslateblue);
min-height: 100vh;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class='container'>
<svg viewBox='0 0 100 100' preserveAspectRatio='none'>
<path d='M4,2 L98,2 98,96 4,2z M2,4 L2,98 96,98 2,4z' vector-effect='non-scaling-stroke' />
</svg>
</div>
Note: With any of the approaches mentioned above (or those given in other answers), you cannot make the content to remain within the boundaries of those triangles. Text can be placed upon them but the text cannot be contained within those boundaries unless the CSS Shapes module's shape-inside property is fully implemented.
Just don't give width and height will make triangle.
.triangle1 {
border-right: 30px solid transparent;
border-bottom: 30px solid #4c4c4c;
position: fixed;
}
Working Fiddle
As per your image here i have created two reverse triangle.
.triangle1 {
border-right: 100px solid transparent;
border-bottom: 100px solid #4c4c4c;
position: fixed;
}
.triangle2 {
border-left: 100px solid transparent;
border-top: 100px solid #4c4c4c;
position: fixed;
margin-left: 3px;
}
<div class="triangle1">
</div>
<div class="triangle2">
</div>
Edit:
Here is one way you can add text inside triangle.
Add another text div inside triangle and set it's position.
Fiddle
.triangle1 {
width: 0;
height: 0;
border-left: 0px solid transparent;
border-right: 200px solid transparent;
border-bottom: 150px solid black;
}
For DIV Element 1. For the second just make a square and render the triangle on the top of the square.
Html code :
<div id="DIV-Element1"></div>
<div id="DIV-Element2"></div>
Css :
#DIV-Element1 { width: 0; height: 0; border-bottom: 100px solid black; border-right: 100px solid transparent; }
#DIV-Element2 { width: 0; height: 0; margin-left: 15px;border-top: 100px solid black; border-left: 100px solid transparent; }
you can adjust your triangle by changing border
I hope this will work

How can I make a similar shape to a parallelogram in css?

I am trying to make a shape similar to a parallelogram, but without the angle on the right side. So it will keep its straight up and down line on the right, but the left side will keep its angle. Here is a fiddle: http://jsfiddle.net/2hj88xts/
CSS:
#parallelogram {
width: 250px;
height: 100px;
transform: skew(-15deg);
background: red;
}
You could try using a border-left with transparent as the color and abandon the *-transform's altogether. This would require a CSS change but no additional HTML markup:
Current Angle:
#parallelogram {
width: 250px;
height: 0;
border-bottom: 100px solid red;
border-left: 30px solid transparent;
margin-left: 10px;
}
<div id="parallelogram"></div>
To adjust the left angle simply tweak the border-left pixel amount. The larger the pixel amount, the more shallow the angle. The smaller the pixel amount, the steeper the angle.
Shallow Angle:
#parallelogram {
width: 250px;
height: 0;
border-bottom: 100px solid red;
border-left: 100px solid transparent;
margin-left: 10px;
}
<div id="parallelogram"></div>
Steep Angle:
#parallelogram {
width: 250px;
height: 0;
border-bottom: 100px solid red;
border-left: 15px solid transparent;
margin-left: 10px;
}
<div id="parallelogram"></div>
Use a pseudo element :
#parallelogram {
width: 250px;
height: 100px;
background: red;
margin-left: 100px;
position:relative;
}
#parallelogram:before{
content: '';
position:absolute;
width: 0;
height: 0;
border-style: solid;
border-width: 0 0 100px 40px;
border-color: transparent transparent red transparent;
left: -40px;
}
<div id="parallelogram"></div>
JSFiddle
Update
If you love living on the edge, try clip-path:
#parallelogram{
width: 250px;
height: 100px;
background: red;
-webkit-clip-path: polygon(29% 0, 100% 0, 100% 100%, 0% 100%);
clip-path: polygon(29% 0, 100% 0, 100% 100%, 0% 100%);
}
<div id="parallelogram"></div>
JSFiddle
Ok, So combine two divs together and remove the effect from the right div and pull it left to overlap the edge of the left div. Do something like this:
#parallelogram {
width: 250px;
height: 100px;
-webkit-transform: skew(-15deg );
-moz-transform: skew(-15deg);
-o-transform: skew(-15deg);
background: red;
margin-left:10px;
display:inline-block;
}
#end {
width: 250px;
height: 100px;
background: red;
display:inline-block;
margin-left:-20px;
}
<div>
<div id="parallelogram">
</div>
<div id="end">
</div>
</div>
Here is a svg solution without any CSS.
<svg>
<path d="M60,0 L250,0 L250,100 20,100z" fill="red" />
</svg>

Granularity of shapes in CSS

I'm trying to achieve this in html:
I do it like this (in red to make it more obvious):
span.triangle-bottomleft {
width: 0;
height: 0;
border-bottom: 50px solid red;
border-right: 500px solid transparent;
}
span.triangle-bottomright {
width: 0;
height: 0;
border-bottom: 50px solid red;
border-left: 500px solid transparent;
}
The result is this:
The pixel is not very granular. Is it possible to make the sloped line smoother?
Thanks!
Based on my little experiment, it seems that anti-aliasing works better with the border width hack than the background image solution. There is no easy CSS-only solution to what you're looking for, unfortunately.
Give the following markup:
<div class="chevron"></div>
You can use the following strategies (view all of this in this fiddle: http://jsfiddle.net/teddyrised/dL2wswfm/1/)
The background image hack
This is achieved by specifying multiple background images, which is supported in CSS3 and modern browsers.
.chevron {
background-image:
linear-gradient(to bottom left, #ccc 0%, #ccc 50%, transparent 50%, transparent 100%),
linear-gradient(to bottom right, #ccc 0%, #ccc 50%, transparent 50%, transparent 100%);
background-position:
bottom left,
bottom right;
background-repeat: no-repeat;
background-size: 50% 100%;
background-color: red;
width: 100%;
height: 50px;
}
The border hack
While the border hack provides the best visual result, it is not possible to use percentage values for the left and right border widths — you will either have to use absolute values (px, em...) or relative values with respect to the viewport (vh, vw, vmin, vmax). This limits the application to divs that stretches to a known percentage of the viewport:
.chevron {
background-color: red;
position: relative;
width: 100%;
height: 50px;
}
.chevron::before {
box-sizing: border-box;
position: absolute;
top: 0;
left: 0;
right: 50%;
bottom: 0;
content: '';
border-top: 50px solid #ccc;
border-left: 50vw solid transparent;
}
.chevron::after {
box-sizing: border-box;
position: absolute;
top: 0;
left: 50%;
right: 0;
bottom: 0;
content: '';
border-top: 50px solid #ccc;
border-right: 50vw solid transparent;
}
See fiddle here: http://jsfiddle.net/teddyrised/dL2wswfm/1/

Make div with bottom triangle

I have been trying to do the white shape with a div:
http://sircat.net/joomla/sircat/mies/2.png
how do I get the diagonal shapes of the bottom of the div?
I have this for the div:
width: 620px;
height: 440px;
background-color: white;
thank you
Edit: just forget the bg behind the div, I want to make the div with the diagonal borders, not with the help of the bg because it is in the top layer
You can also use borders and the :after pseudo selector: http://jsfiddle.net/qQySU/
#pointed {
position: relative;
margin: 0 auto;
width: 200px;
height: 200px;
background-color: white;
}
#pointed:after,
#pointed::after {
position: absolute;
top: 100%;
left: 50%;
margin-left: -50%;
content: '';
width: 0;
height: 0;
border-top: solid 150px red;
border-left: solid 100px transparent;
border-right: solid 100px transparent;
}
I've colored the tip for easy identification of the borders. Play around the border widths on the last 3 lines to get the tip you want.
Edit.:
Reference for compability: http://caniuse.com/css-gencontent
Edit 2:
In exchange for semantics, you can get it more crossbrowser you can place the stle on a inner element instead of on the :after pseudo selector.
Simplest (least amount of code) method: just use a CSS linear-gradient http://dabblet.com/gist/3610406
HTML:
<div class='box'>Text goes here...</div>
CSS:
.box {
width: 26em;
min-height: 31em;
padding: 1em;
outline: solid 1px lightblue;
margin: 0 auto;
background: linear-gradient(45deg, dimgrey 47%, black 50%, transparent 50%)
no-repeat 0 100%,
linear-gradient(-45deg, dimgrey 47%, black 50%, transparent 50%)
no-repeat 100% 100%;;
background-size: 50% 14em;
}
Better compatibility & better looking: you could use a pseudo-element with a box-shadow: http://dabblet.com/gist/3610548
HTML:
<div class='box'>text goes here... hover me ;)</div>
CSS:
html { background: darkgrey; }
.box {
box-sizing: border-box;
position: relative;
width: 20em;
height: 20em;
padding: 1em;
margin: 3em auto 0;
background: white;
}
.box:before {
position: absolute;
right: 14.65%; /* 50% - 35.35% */ bottom: -35.35%; /* half of 70.71% */
width: 70.71%; /* 100%*sqrt(2)/2 */
height: 70.71%;
box-shadow: 2px 2px 1px dimgrey;
transform: rotate(45deg);
background: white;
content: '';
}
.box:hover, .box:hover:before {
background: plum;
}