I'm trying to create two elongated hexagons in like:
The main features should be:
possibility to add a gradient background
possibility to add a gradient border
text could be two-lined or single-lined
responsive in a Bootstrap-grid (nice to have) - angles of corners should be always the same.
According to Elongated hexagon shaped button using only one element the best solution so far is like
https://jsfiddle.net/veuc78af/:
/*hexagons*/
.hexagon {
box-sizing: border-box;
position: relative;
display: inline-block;
min-width: 200px;
height: 80px;
margin: 40px auto;
color: #fd0;
text-align: center;
text-decoration: none;
line-height: 80px;
}
.hexagon:before, .hexagon:after {
position: absolute;
content:'';
width: 100%;
left: 0px;
height: 34px;
z-index: -1;
}
.hexagon:before {
transform: perspective(15px) rotateX(3deg);
}
.hexagon:after {
top: 40px;
transform: perspective(15px) rotateX(-3deg);
}
/* hexagon Border Style */
.hexagon.border:before, .hexagon.border:after {
border: 4px solid #fd0;
}
.hexagon.border:before {
border-bottom: none;
/* to prevent the border-line showing up in the middle of the shape */
}
.hexagon.border:after {
border-top: none;
/* to prevent the border-line showing up in the middle of the shape */
}
/* hexagon hover styles */
.hexagon.border:hover:before, .hexagon.border:hover:after {
background: #fd0;
}
.hexagon.border:hover {
color: #fff;
}
The main problem with this solution is that it isn't possible to create a gradient background. So this isn't working in my case.
Is there any possibility to do that?
The main platform for this project is Safari on an iPad2.
Using CSS Clip Path:
The main platform for this project is Safari on an iPad2.
Since, your main platform is Safari and it does support CSS clip-path with shapes, you can make use of that feature to create the elongated hexagons like in the below demo.
Output produced by this approach will support (a) gradient backgrounds (b) a gradient border which is mimicked by placing a pseudo-element with a very similar clip-path but smaller dimensions (c) two lines of text (d) also maintain the angles of the corners because the points are at a fixed px distance.
.hex {
position: relative;
float: left;
height: 100px;
min-width: 100px;
padding: 12px;
margin: 4px;
font-weight: bold;
text-align: center;
background: linear-gradient(to right, rgb(199, 41, 41), rgb(243, 67, 54));
-webkit-clip-path: polygon(25px 0px, calc(100% - 25px) 0px, 100% 50%, calc(100% - 25px) 100%, 25px 100%, 0px 50%);
}
.hex.gradient-bg {
color: white;
}
.hex.gradient-border {
color: rgb(199, 41, 41);
}
.hex:before {
position: absolute;
content: '';
height: calc(100% - 14px); /* 100% - 2 * border width */
width: calc(100% - 14px); /* 100% - 2 * border width */
left: 7px; /* border width */
top: 7px; /* border width */
-webkit-clip-path: polygon(22px 0px, calc(100% - 22px) 0px, 100% 50%, calc(100% - 22px) 100%, 22px 100%, 0px 50%);
z-index: -1;
}
.hex.gradient-bg:before {
background: linear-gradient(to right, rgb(199, 41, 41), rgb(243, 67, 54));
}
.hex.gradient-border:before {
background: rgb(245, 246, 248);
}
span {
display: block;
margin-top: 50px;
padding: 8px;
transform: translateY(-50%);
}
<div class='hex gradient-border'>
<span>Some text</span>
</div>
<div class='hex gradient-bg'>
<span>Some very lengthy text</span>
</div>
<div class='hex gradient-bg'>
<span>Some very lengthy text
<br/>with line break</span>
</div>
<div class='hex gradient-bg'>
<span>Some very lengthy text
without line break</span>
</div>
Using SVG:
The same can be done using SVG also like in the below demo. It just requires a path to be created in the form of a hexagon and then for that path image to be placed behind the container.
The only drawback is that unlike CSS clip-path there is no non-JS way to get the angles to stay the same.
.hex {
position: relative;
height: 100px;
min-width: 100px;
padding: 12px 24px;
margin: 4px;
float: left;
font-weight: bold;
text-align: center;
}
.hex.gradient-bg {
color: white;
}
.hex.gradient-border {
color: rgb(199, 41, 41);
}
.hex svg {
position: absolute;
height: 100%;
width: 100%;
top: 0px;
left: 0px;
z-index: -1;
}
path {
stroke: url(#brdgrad);
stroke-width: 7; /* border width */
}
.hex.gradient-bg path {
fill: url(#bggrad);
}
.hex.gradient-border path {
fill: rgb(245, 246, 248);
}
span {
display: block;
margin-top: 50px;
padding: 8px;
transform: translateY(-50%);
}
<svg width='0' height='0'>
<defs>
<linearGradient id='bggrad'>
<stop offset='0%' stop-color='rgb(199, 41, 41)' />
<stop offset='100%' stop-color='rgb(243, 67, 54)' />
</linearGradient>
<linearGradient id='brdgrad'>
<stop offset='0%' stop-color='rgb(199, 41, 41)' />
<stop offset='100%' stop-color='rgb(243, 67, 54)' />
</linearGradient>
</defs>
</svg>
<div class='hex gradient-border'>
<svg viewBox='0 0 100 100' preserveAspectRatio='none'>
<path d='M25,7 L75,7 93,50 75,93 25,93 7,50z' vector-effect='non-scaling-stroke' />
</svg>
<span>Some text</span>
</div>
<div class='hex gradient-bg'>
<svg viewBox='0 0 100 100' preserveAspectRatio='none'>
<path d='M25,7 L75,7 93,50 75,93 25,93 7,50z' vector-effect='non-scaling-stroke' />
</svg>
<span>Some very lengthy text</span>
</div>
<div class='hex gradient-bg'>
<svg viewBox='0 0 100 100' preserveAspectRatio='none'>
<path d='M25,7 L75,7 93,50 75,93 25,93 7,50z' vector-effect='non-scaling-stroke' />
</svg>
<span>Some very lengthy text
<br>with line break.</span>
</div>
<div class='hex gradient-bg'>
<svg viewBox='0 0 100 100' preserveAspectRatio='none'>
<path d='M25,7 L75,7 93,50 75,93 25,93 7,50z' vector-effect='non-scaling-stroke' />
</svg>
<span>Some lengthy text
without line break.</span>
</div>
(Don't be put off by how lengthy the SVG code is, it is so big only because I've repeated it more than once - once for each container. That can be reduced.)
.hexagon {
position: relative;
width: 180px;
height: 103.92px;
background-color: #ffffff;
margin: 51.96px 0;
border-left: solid 5px #808080;
border-right: solid 5px #808080;
}
.hexagon:before,
.hexagon:after {
content: "";
position: absolute;
z-index: 1;
width: 127.28px;
height: 127.28px;
-webkit-transform: scaleY(0.5774) rotate(-45deg);
-ms-transform: scaleY(0.5774) rotate(-45deg);
transform: scaleY(0.5774) rotate(-45deg);
background-color: inherit;
left: 21.3604px;
}
.hexagon:before {
top: -63.6396px;
border-top: solid 7.0711px #808080;
border-right: solid 7.0711px #808080;
}
.hexagon:after {
bottom: -63.6396px;
border-bottom: solid 7.0711px #808080;
border-left: solid 7.0711px #808080;
}
.hexText{
position: absolute;
top: 59px;
z-index: 999;
left: 12%;
text-align:center;
}
.bgGrey{
background:#e7e6e6 !important;
}
<div class="row">
<div class="col-md-3 col-xs-12">
<div class="hexagon"></div>
<p class="hexText">Up to 20% increase<br />in sales with<br />Cross sell & Up sell</p>
</div>
<div class="col-md-3 col-xs-12">
<div class="hexagon bgGrey"></div>
<p class="hexText">Up to 35%reduction<br />in print ,postage ,<br />logistic & back<br />office cost</p>
</div>
<div class="col-md-3 col-xs-12">
<div class="hexagon"></div>
<p class="hexText">Scalable100+million <br />statements<br />processed & <br />distributed monthly </p>
</div>
<div class="col-md-3 col-xs-12">
<div class="hexagon bgGrey"></div>
<p class="hexText">Up to 35%reduction<br />in print ,postage ,<br />logistic & back<br />office cost</p>
</div>
</div>
Related
I'm trying to improve my css skills, and wanted to draw like a moon and outline it. I mad this by using 2 circles and the second one has the same color as the background so it look like a moon. However now i want to outline/ give it a border but i don't know how to do this, because the other parts are overlapped with the secon circle.
body{
position: relative;
background-color: white;
padding-left: 40%;
}
#div1{
position: absolute;
height: 400px;
width: 400px;
border-radius: 100%;
background-image: linear-gradient(45deg, #050182, #51bfdb);
border: 3px solid black;
}
#div2{
position: absolute;
height: 350px;
width: 350px;
background-color: white;
border-radius: 50%;
margin-left: 110px;
margin-top: 25px;
z-index: 2;
}
<div class="container">
<div id="div1"></div>
<div id="div2"></div>
</div>
I would simplify your code using mask then I will rely on drop-shadow filter for the outline
#div1{
filter:drop-shadow(0 0 1px #000) drop-shadow(0 0 0 #000) drop-shadow(0 0 0 #000);
}
#div1:before {
content:"";
display:block;
height: 200px;
width: 200px;
border-radius: 50%;
background-image: linear-gradient(45deg, #050182, #51bfdb);
-webkit-mask: radial-gradient(circle 100px at 80% 50%,#0000 98%,#000);
}
<div id="div1"></div>
You can add border left property to div2 for desired result.
body{
position: relative;
background-color: white;
padding-left: 40%;
}
#div1{
position: absolute;
height: 400px;
width: 400px;
border-radius: 100%;
background-image: linear-gradient(45deg, #050182, #51bfdb);
border: 3px solid black;
}
#div2{
position: absolute;
height: 350px;
width: 350px;
background-color: white;
border-radius: 50%;
margin-left: 110px;
margin-top: 25px;
z-index: 2;
border-left: 3px solid black;
}
<div class="container">
<div id="div1"></div>
<div id="div2"></div>
</div>
Like Justinas already commented, you're kind of trying to do SVG's job in CSS here, which is pretty clunky and inefficient.
If you know a little HTML and CSS, which it seems you do, then SVG will feel like just more of the same.
SVG will just look like a couple new HTML elements to you, and you just sprinkle it right into your HTML; It also just uses the same CSS stylesheet that as your HTML already uses.
To illustrate, run this snippet here; just a couple lines of CSS and some SVG, i'm sure you can tell what 90% of it means instantly.
body { background-color: #FFF; }
svg { background-color: #CCC; }
.gradient_start { stop-color:rgb(255, 255, 0); stop-opacity: 1; }
.gradient_end { stop-color:rgb(255, 0, 0); stop-opacity: 1; }
text { font-family: "Verdana"; font-size: 32pt; }
<html>
<body>
<svg width="400" height="200">
<defs>
<linearGradient id="mygradient" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" class="gradient_start" />
<stop offset="100%" class="gradient_end" />
</linearGradient>
</defs>
<ellipse cx="200" cy="70" rx="85" ry="55" fill="url(#mygradient)" />
<text x="150" y="86" fill="#ffffff">
Turtles !
</text>
</svg>
</body>
</html>
In SVG you have access to a lot more drawing elements, such as the <ellipse> used in this example.
Look at the result, using the border-left property.
body{
position: relative;
background-color: white;
padding-left: 40%;
}
#div1{
position: absolute;
height: 400px;
width: 400px;
border-radius: 100%;
background-image: linear-gradient(45deg, #050182, #51bfdb);
border: 3px solid black;
}
#div2{
position: absolute;
height: 350px;
width: 350px;
background-color: white;
border-radius: 50%;
margin-left: 110px;
margin-top: 25px;
z-index: 2;
border-left: 2px solid black;
}
<div class="container">
<div id="div1"></div>
<div id="div2"></div>
</div>
I have based my code out of this CSS Shapes Layout Pyramid from codepen: https://codepen.io/s-gupta/pen/jOMGbMX
I'm quite happy with the shape of my pyramid, but I also want a text box to appear to the right of each pyramid step when you hover over the element. I based my text box code on https://www.w3schools.com/css/css_tooltip.asp
However, as you see, the text box appears within the wrapper/pyramid, not outside of it. The text in the text box will be quite long, so it cannot be within the pyramid.
How can I make it go outside (and preferably to the right of the pyramid) ?
I'm quite new to CSS/HTML, but I'm trying to learn - Hope somebody out there can help me :)
body {
/*background: #333;
font-family: "SF UI Text", "Avenir", "Helvetica", arial, san-serif;
color: #888;*/
}
.wrapper {
margin: 5vh auto 0;
}
.pyramid {
float: left;
shape-outside:polygon(310px 0px, 130px 405px, 558px 405px);
padding-right:60px;
width: 700px;
height: 500px;
}
.zone {
padding:40px 0;
margin: 0 auto;
text-align:center;
color: black;
background-blend-mode:darken;
transition: 0.5s;
}
.zone:nth-child(1){
background:rgba(248,153,46); /* url("https://pixabay.com/static/uploads/photo/2016/01/05/13/34/laugenbrotchen-1122509_960_720.jpg") center / cover;*/
width: 20%;
clip-path:url("#part1");
clip-path:polygon(50% 0%,0%,100% 100%, 0% 100%);
/*-webkit-clip-path:polygon(50% 0%,100% 100%, 0% 100%);*/
}
.zone:nth-child(2){ background:rgba(248,153,46);
width: 40%;
clip-path:url("#part2");
clip-path:polygon(40% 0%,0%,60% 0, 100% 100%,0% 100%);
/*-webkit-clip-path:polygon(25% 0%,75% 0, 100% 100%,0% 100%);*/
}
.zone:nth-child(3){
width: 60%;
background:rgba(248,153,46);
clip-path:url("#part3");
clip-path:polygon(30% 0,0%, 70% 0, 100% 100%,0% 100%);
/*-webkit-clip-path:polygon(16.5% 0, 83% 0, 100% 100%,0% 100%);*/
}
.zone:nth-child(4){
background:rgba(248,153,46);
width: 80%;
clip-path:url("#part4");
clip-path:polygon(20% 0, 0%,80% 0, 100% 100%,0% 100%);
/*-webkit-clip-path:polygon(12.5% 0,87.5% 0, 100% 100%,0% 100%);*/
}
.zone:nth-child(5){
background:rgba(248,153,46);
width: 100%;
clip-path:url("#part5");
clip-path:polygon(10% 0, 0%,100% 0, 100% 100%,0% 100%);
/*-webkit-clip-path:polygon(12.5% 0,87.5% 0, 100% 100%,0% 100%);*/
}
/*.zone:hover {
background-color: rgba(118,113,113);
color: white;
}
*/
.zone .arrowtext {
visibility: hidden;
width: 120px;
background-color: black;
color: #fff;
text-align: center;
padding: 5px 0;
border-radius: 6px;
top: -5px;
left: 105%;
}
.zone .arrowtext::after {
content: " ";
position: relative;
top: 50%;
right: 100%; /* To the left of the tooltip */
margin-top: -5px;
border-width: 5px;
border-style: solid;
border-color: transparent black transparent transparent;
}
.zone:hover {
background-color: rgba(118,113,113);
color: white;
}
.zone:hover .arrowtext{
visibility: visible;
}
<div class="wrapper">
<div class="pyramid">
<div class="zone">0. zero
<span class="arrowtext">Tooltip text</span></div>
<div class="zone">1. One</div>
<div class="zone">2. Two</div>
<div class="zone">3. Three</div>
<div class="zone">4. Four</div>
</div>
<svg width="0" height="0">
<defs>
<clipPath id="part1" clipPathUnits= "objectBoundingBox">
<polygon points= "0.5 0, 1 1, 0 1"/>
</clipPath>
<clipPath id="part2" clipPathUnits= "objectBoundingBox">
<polygon points= "0.25 0,0.75 0, 1 1, 0 1"/>
</clipPath>
<clipPath id="part3" clipPathUnits= "objectBoundingBox">
<polygon points= "0.165 0,0.83 0, 1 1, 0 1"/>
</clipPath>
<clipPath id="part4" clipPathUnits= "objectBoundingBox">
<polygon points= "0.125 0,0.875 0, 1 1, 0 1"/>
</clipPath>
<clipPath id="part5" clipPathUnits= "objectBoundingBox">
<polygon points= "0.1 0,0.9 0, 1 1, 0 1"/>
</clipPath>
</defs>
</svg>
And further, how could I make the arrowtext go over several sentences? I figured I can make the width wider and reduce the clip path so that the triangle takes up less of the area. That solves the problem of making whole 1-2 lines visible, but what about getting text that goes over 2 lines? I've tried z-index for example, but does not work. In other words I'm looking for a way to make the text expand further than only the height of the hovered element or zone.
Here is a simplified version where I am reducing the size for the sake of the demo (feel free to update them).
The trick is to create triangle shapes using pseudo element on each "zone" element. By making them relative to "pyramid" they will overlap (creating the illusion of only one). Then by using clip-path:inset(0) on "zone" each one will show one portion on the triangle.
.pyramid {
width: 400px;
margin: auto;
z-index: 0;
position: relative; /* relative on "pyramid" and not "zone" */
}
/* build the triangle as pseudo element fo "zone" */
.zone:before {
content: "";
position: absolute;
inset: 0;
z-index: -1;
background: rgba(248, 153, 46);
/* the pyramid shape */
clip-path: polygon(50% 0, 100% 100%, 0 100%);
transition: 0.5s;
}
.zone {
padding: 20px 0;
text-align: center;
cursor: pointer;
color: black;
clip-path: inset(0); /* clip the triangle to only the shape of each "zone"*/
}
/* using an extra div to correctly place the tooltip*/
.zone > div {
display:inline-block;
position:relative;
}
/* update color on hover */
.zone:hover {
color: white;
}
.zone:hover:before {
background: rgba(118, 113, 113);
}
/**/
.zone .arrowtext {
position: absolute;
visibility: hidden;
white-space:nowrap;
background-color: black;
color: #fff;
padding: 5px;
border-radius: 6px;
top: -5px;
left: 105%;
}
.zone:hover .arrowtext {
visibility: visible;
}
<div class="pyramid">
<div class="zone">
<div>0. zero<span class="arrowtext">Tooltip text</span></div>
</div>
<div class="zone">1. One</div>
<div class="zone">2. Two</div>
<div class="zone">3. Three</div>
<div class="zone">4. Four</div>
</div>
This is the layout I'm looking to achieve:
I've created the hexagon with this css:
.hexagon {
width: 100px;
height: 55px;
background: red;
position: relative;
display:inline-block;
margin:0.2em;
}
.hexagon: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;
}
.hexagon: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;
}
However, I'm looking to find out how to fill them with an image.
Here is a pen:https://codepen.io/1istbesser/pen/ddypXK
How do I put images inside the hexagon so that it covers all of it? If I use background-image on #hexagon1, the image only covers the middle part.
The problem you're going to run into is that using CSS triangles to create a hexagon actually yields square boxes with one or two borders filled in (and the rest transparent). This has two effects:
You can't easily put an image into the filled border so that it's clipped.
You can't make the hexagon - and only the hexagon - clickable: the whole set of rectangles will always be clickable, which will make your layout tricky where they overlap.
You're going to need something that can produce an actual hexagon. Inline SVG with a clip-path is a good fit - unlike clip-path in CSS, it's supported pretty much wherever SVG is. Here's an example:
<svg class="svg-graphic" width="300" height="300" viewBox="0 0 300 300" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" version="1.1">
<defs>
<clipPath id="hexagonal-mask">
<polygon points="300,150 225,280 75,280 0,150 75,20 225,20" />
</clipPath>
</defs>
<image clip-path="url(#hexagonal-mask)" height="100%" width="100%" xlink:href="https://i.imgur.com/grp9BU1.png" preserveAspectRatio="xMidYMin slice"/>
</svg>
Here's a more detailed example showing clickable hexagons, and re-use of the clip path definition:
.svg-template {
position: absolute;
}
.honeycomb {
list-style: none;
margin: 0;
padding: 0;
position: relative;
width: 1200px;
height: 1200px;
border: 1px solid #DDD;
}
.honeycomb li {
margin: 0;
padding: 0;
position: absolute;
}
.honeycomb li:nth-child(1) {
top: 0;
left: 0;
}
.honeycomb li:nth-child(2) {
top: 0;
left: 290px;
}
.honeycomb li:nth-child(3) {
top: 0;
left: 580px;
}
.honeycomb li:nth-child(4) {
top: 240px;
left: 145px;
}
.honeycomb li:nth-child(5) {
top: 240px;
left: 435px;
}
.honeycomb li:nth-child(6) {
top: 240px;
left: 725px;
}
.honeycomb li a {
cursor: pointer;
}
.honeycomb li a:hover image{
opacity: 0.5;
}
<svg class="svg-template" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" version="1.1">
<defs>
<clipPath id="hexagonal-mask">
<polygon points="50 0, 95 25, 95 75, 50 100, 5 75, 5 25" />
</clipPath>
</defs>
</svg>
<ul class="honeycomb">
<li>
<svg width="300" height="300" viewBox="0 0 100 100" >
<a href="#something">
<image clip-path="url(#hexagonal-mask)" height="100%" width="100%" xlink:href="https://i.imgur.com/grp9BU1.png"/>
</a>
</svg>
</li>
<li>
<svg width="300" height="300" viewBox="0 0 100 100" >
<a href="#something">
<image clip-path="url(#hexagonal-mask)" height="100%" width="100%" xlink:href="https://i.imgur.com/grp9BU1.png"/>
</a>
</svg>
</li>
<li>
<svg width="300" height="300" viewBox="0 0 100 100" >
<a href="#something">
<image clip-path="url(#hexagonal-mask)" height="100%" width="100%" xlink:href="https://i.imgur.com/grp9BU1.png"/>
</a>
</svg>
</li>
<li>
<svg width="300" height="300" viewBox="0 0 100 100" >
<a href="#something">
<image clip-path="url(#hexagonal-mask)" height="100%" width="100%" xlink:href="https://i.imgur.com/grp9BU1.png"/>
</a>
</svg>
</li>
<li>
<svg width="300" height="300" viewBox="0 0 100 100" >
<a href="#something">
<image clip-path="url(#hexagonal-mask)" height="100%" width="100%" xlink:href="https://i.imgur.com/grp9BU1.png"/>
</a>
</svg>
</li>
<li>
<svg width="300" height="300" viewBox="0 0 100 100" >
<a href="#something">
<image clip-path="url(#hexagonal-mask)" height="100%" width="100%" xlink:href="https://i.imgur.com/grp9BU1.png"/>
</a>
</svg>
</li>
</ul>
You need to consider another way if you want to use image as background. You are relying on pseudo element so your hexagone is not one element and thus you cannot use background image to cover the whole area.
Here is an idea using clip-path:
* {
background-color: black;
}
section {
margin-top: 3em;
display: flex;
flex-flow: column;
align-items: center;
}
.hexagon {
width: 100px;
height: 100px;
background: url(https://lorempixel.com/100/100/) 0 0/cover no-repeat;
position: relative;
display: inline-block;
margin: -10px 0.2em;
-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%);
}
<section>
<div class="row">
<div class="hexagon" id="hexagon1"></div>
<div class="hexagon" id="hexagon2"></div>
<div class="hexagon" id="hexagon3"></div>
<div class="hexagon" id="hexagon4"></div>
</div>
<div class="row">
<div class="hexagon" id="hexagon5"></div>
<div class="hexagon" id="hexagon6"></div>
<div class="hexagon" id="hexagon7"></div>
<div class="hexagon" id="hexagon8"></div>
<div class="hexagon" id="hexagon9"></div>
</div>
</section>
What you could do is draw an SVG and than put the image as mask in css
https://codepen.io/noahblon/post/coloring-svgs-in-css-background-images
*{
background-color:black;
}
section{
margin-top:3em;
display:flex;
flex-flow: column;
align-items: center;
}
.hexagon {
width: 100px;
height: 110px;
background: red;
position: relative;
display:inline-block;
margin:0.2em;
-webkit-mask:url(https://svgshare.com/i/5Fk.svg) no-repeat 50% 50%;
mask:url(https://svgshare.com/i/5Fk.svg) no-repeat 50% 50%;
background-image: url('https://img1.ibxk.com.br/2017/07/13/13160112901226.jpg?w=700');
background-size: cover;
background-position: center;
}
.row{
text-align: center;
margin-top: -25px
}
<section>
<div class="row">
<div class="hexagon" id="hexagon1"></div>
<div class="hexagon" id="hexagon2"></div>
<div class="hexagon" id="hexagon3"></div>
<div class="hexagon" id="hexagon4"></div>
<div class="row">
<div class="hexagon" id="hexagon5"></div>
<div class="hexagon" id="hexagon6"></div>
<div class="hexagon" id="hexagon7"></div>
</div>
<div class="row">
<div class="hexagon" id="hexagon8"></div>
<div class="hexagon" id="hexagon9"></div>
</div>
</section>
I made this code
Codepen
I changed the way you draw the element, instead adding the border top with the color red, I added the sides with a background, but you'd need to know the background-color of the page to do that, so I put the image above the box and the before and after above the image
CSS
*{
background-color:black;
}
section{
margin-top:3em;
display:flex;
flex-flow: column;
align-items: center;
}
.hexagon {
width: 100px;
height: 110px;
background: red;
position: relative;
display:inline-block;
margin:0.2em;
overflow: hidden;
}
.hexagon img{
position: absolute;
left: 50%;
top: 50%;
min-width: 100%;
min-height: 100%;
height: 100%;
transform: translate(-50%, -50%);
z-index: 1;
}
.hexagon:before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 0;
height: 0;
border-right: 50px solid black;
border-left: 50px solid black;
border-bottom: 25px solid transparent;
z-index: 2;
}
.hexagon:after {
content: "";
position: absolute;
bottom: 0;
left: 0;
width: 0;
height: 0;
border-right: 50px solid black;
border-left: 50px solid black;
border-top: 25px solid transparent;
z-index: 2;
}
.row{
margin-top:1.3em;
}
.hexagon#hexagon2{
background-color: purple;
}
.hexagon#hexagon2:before{
border-bottom-color: purple;
}
.hexagon#hexagon2:after{
border-top-color: purple;
}
.hexagon#hexagon3{
background-color: white;
}
.hexagon#hexagon3:before{
border-bottom-color: white;
}
.hexagon#hexagon3:after{
border-top-color: white;
}
.hexagon#hexagon4{
background-color: orange;
}
.hexagon#hexagon4:before{
border-bottom-color: orange;
}
.hexagon#hexagon4:after{
border-top-color: orange;
}
I want my svg images to be on bottom of my block (position:absolute, bottom:0). But in Internet Explorer it doesn't work (displays in the center). I can set width and height to svg and it will work somehow, but it will broke on another device with smaller/bigger screen size. How can I resolve this problem? Thank you!
Here is the code codepen
.wrapper {
padding: 150px 20px 50px;
text-align: center;
color: #fff;
}
.main {
background-color: #000;
line-height: 48px;
position: relative;
}
svg {
position: absolute;
bottom: 0;
}
.left {
left: 0;
}
.right {
right: 0;
}
<div class="main">
<div class="wrapper">
<div class="text">Some text here</div>
<button>click</button>
</div>
<svg class="left" fill="#fff" viewBox="0 0 1300 150" width="50%">
<polygon points="0,0 0,150 1300,150"></polygon>
</svg>
<svg class="right" fill="#fff" viewBox="0 0 1300 150" width="50%">
<polygon points="1300,0 0,150 1300,150"></polygon>
</svg>
</div>
You can achieve the same with using either simple divs or with pseudo elements. The following is an example I created to demonstrate both approaches.
https://codepen.io/Nasir_T/pen/oEYYob
The example uses position along with border to set the bottom design the way your want. You can use the div solution if you want to place images in it or use the pseudo solution if only want to show arrow cut in the design at the bottom.
If you want a background image, why not use a background-image??
.wrapper {
padding: 150px 20px 50px;
text-align: center;
color: #fff;
}
.main {
background-color: #000;
line-height: 48px;
position: relative;
background-image: url('data:image/svg+xml,<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg viewBox="0 0 52 3" xmlns="http://www.w3.org/2000/svg"><polygon points="0,0 26,3 52,0 52,3 0,3" fill="#fff" /></svg>');
background-repeat: no-repeat;
background-position: center bottom;
}
<div class="main">
<div class="wrapper">
<div class="text">Some text here</div>
<button>click</button>
</div>
</div>
This can be accomplished using CSS alone.
We can make triangle shape in CSS. Stick a triangle at the bottom of your main container. Will give the same effect.
.wrapper {
padding: 110px 20px 50px;
text-align: center;
color: #fff;
}
.main {
background-color: #000;
line-height: 48px;
position: relative;
width: 1000px;
}
.arrow-down {
width: 0;
height: 0;
border-left: 500px solid transparent;
border-right: 500px solid transparent;
border-top: 50px solid #000;
position:absolute;
bottom:-50px;
}
svg {
position: absolute;
bottom: 0;
}
.left {
left:0;
}
.right {
right:0;
}
<div class="main">
<div class="wrapper">
<div class="text">Some text here</div>
<button>click</button>
</div>
<div class="arrow-down">
</div>
</div>
I'm trying to create two elongated hexagons in like:
The main features should be:
possibility to add a gradient background
possibility to add a gradient border
text could be two-lined or single-lined
responsive in a Bootstrap-grid (nice to have) - angles of corners should be always the same.
According to Elongated hexagon shaped button using only one element the best solution so far is like
https://jsfiddle.net/veuc78af/:
/*hexagons*/
.hexagon {
box-sizing: border-box;
position: relative;
display: inline-block;
min-width: 200px;
height: 80px;
margin: 40px auto;
color: #fd0;
text-align: center;
text-decoration: none;
line-height: 80px;
}
.hexagon:before, .hexagon:after {
position: absolute;
content:'';
width: 100%;
left: 0px;
height: 34px;
z-index: -1;
}
.hexagon:before {
transform: perspective(15px) rotateX(3deg);
}
.hexagon:after {
top: 40px;
transform: perspective(15px) rotateX(-3deg);
}
/* hexagon Border Style */
.hexagon.border:before, .hexagon.border:after {
border: 4px solid #fd0;
}
.hexagon.border:before {
border-bottom: none;
/* to prevent the border-line showing up in the middle of the shape */
}
.hexagon.border:after {
border-top: none;
/* to prevent the border-line showing up in the middle of the shape */
}
/* hexagon hover styles */
.hexagon.border:hover:before, .hexagon.border:hover:after {
background: #fd0;
}
.hexagon.border:hover {
color: #fff;
}
The main problem with this solution is that it isn't possible to create a gradient background. So this isn't working in my case.
Is there any possibility to do that?
The main platform for this project is Safari on an iPad2.
Using CSS Clip Path:
The main platform for this project is Safari on an iPad2.
Since, your main platform is Safari and it does support CSS clip-path with shapes, you can make use of that feature to create the elongated hexagons like in the below demo.
Output produced by this approach will support (a) gradient backgrounds (b) a gradient border which is mimicked by placing a pseudo-element with a very similar clip-path but smaller dimensions (c) two lines of text (d) also maintain the angles of the corners because the points are at a fixed px distance.
.hex {
position: relative;
float: left;
height: 100px;
min-width: 100px;
padding: 12px;
margin: 4px;
font-weight: bold;
text-align: center;
background: linear-gradient(to right, rgb(199, 41, 41), rgb(243, 67, 54));
-webkit-clip-path: polygon(25px 0px, calc(100% - 25px) 0px, 100% 50%, calc(100% - 25px) 100%, 25px 100%, 0px 50%);
}
.hex.gradient-bg {
color: white;
}
.hex.gradient-border {
color: rgb(199, 41, 41);
}
.hex:before {
position: absolute;
content: '';
height: calc(100% - 14px); /* 100% - 2 * border width */
width: calc(100% - 14px); /* 100% - 2 * border width */
left: 7px; /* border width */
top: 7px; /* border width */
-webkit-clip-path: polygon(22px 0px, calc(100% - 22px) 0px, 100% 50%, calc(100% - 22px) 100%, 22px 100%, 0px 50%);
z-index: -1;
}
.hex.gradient-bg:before {
background: linear-gradient(to right, rgb(199, 41, 41), rgb(243, 67, 54));
}
.hex.gradient-border:before {
background: rgb(245, 246, 248);
}
span {
display: block;
margin-top: 50px;
padding: 8px;
transform: translateY(-50%);
}
<div class='hex gradient-border'>
<span>Some text</span>
</div>
<div class='hex gradient-bg'>
<span>Some very lengthy text</span>
</div>
<div class='hex gradient-bg'>
<span>Some very lengthy text
<br/>with line break</span>
</div>
<div class='hex gradient-bg'>
<span>Some very lengthy text
without line break</span>
</div>
Using SVG:
The same can be done using SVG also like in the below demo. It just requires a path to be created in the form of a hexagon and then for that path image to be placed behind the container.
The only drawback is that unlike CSS clip-path there is no non-JS way to get the angles to stay the same.
.hex {
position: relative;
height: 100px;
min-width: 100px;
padding: 12px 24px;
margin: 4px;
float: left;
font-weight: bold;
text-align: center;
}
.hex.gradient-bg {
color: white;
}
.hex.gradient-border {
color: rgb(199, 41, 41);
}
.hex svg {
position: absolute;
height: 100%;
width: 100%;
top: 0px;
left: 0px;
z-index: -1;
}
path {
stroke: url(#brdgrad);
stroke-width: 7; /* border width */
}
.hex.gradient-bg path {
fill: url(#bggrad);
}
.hex.gradient-border path {
fill: rgb(245, 246, 248);
}
span {
display: block;
margin-top: 50px;
padding: 8px;
transform: translateY(-50%);
}
<svg width='0' height='0'>
<defs>
<linearGradient id='bggrad'>
<stop offset='0%' stop-color='rgb(199, 41, 41)' />
<stop offset='100%' stop-color='rgb(243, 67, 54)' />
</linearGradient>
<linearGradient id='brdgrad'>
<stop offset='0%' stop-color='rgb(199, 41, 41)' />
<stop offset='100%' stop-color='rgb(243, 67, 54)' />
</linearGradient>
</defs>
</svg>
<div class='hex gradient-border'>
<svg viewBox='0 0 100 100' preserveAspectRatio='none'>
<path d='M25,7 L75,7 93,50 75,93 25,93 7,50z' vector-effect='non-scaling-stroke' />
</svg>
<span>Some text</span>
</div>
<div class='hex gradient-bg'>
<svg viewBox='0 0 100 100' preserveAspectRatio='none'>
<path d='M25,7 L75,7 93,50 75,93 25,93 7,50z' vector-effect='non-scaling-stroke' />
</svg>
<span>Some very lengthy text</span>
</div>
<div class='hex gradient-bg'>
<svg viewBox='0 0 100 100' preserveAspectRatio='none'>
<path d='M25,7 L75,7 93,50 75,93 25,93 7,50z' vector-effect='non-scaling-stroke' />
</svg>
<span>Some very lengthy text
<br>with line break.</span>
</div>
<div class='hex gradient-bg'>
<svg viewBox='0 0 100 100' preserveAspectRatio='none'>
<path d='M25,7 L75,7 93,50 75,93 25,93 7,50z' vector-effect='non-scaling-stroke' />
</svg>
<span>Some lengthy text
without line break.</span>
</div>
(Don't be put off by how lengthy the SVG code is, it is so big only because I've repeated it more than once - once for each container. That can be reduced.)
.hexagon {
position: relative;
width: 180px;
height: 103.92px;
background-color: #ffffff;
margin: 51.96px 0;
border-left: solid 5px #808080;
border-right: solid 5px #808080;
}
.hexagon:before,
.hexagon:after {
content: "";
position: absolute;
z-index: 1;
width: 127.28px;
height: 127.28px;
-webkit-transform: scaleY(0.5774) rotate(-45deg);
-ms-transform: scaleY(0.5774) rotate(-45deg);
transform: scaleY(0.5774) rotate(-45deg);
background-color: inherit;
left: 21.3604px;
}
.hexagon:before {
top: -63.6396px;
border-top: solid 7.0711px #808080;
border-right: solid 7.0711px #808080;
}
.hexagon:after {
bottom: -63.6396px;
border-bottom: solid 7.0711px #808080;
border-left: solid 7.0711px #808080;
}
.hexText{
position: absolute;
top: 59px;
z-index: 999;
left: 12%;
text-align:center;
}
.bgGrey{
background:#e7e6e6 !important;
}
<div class="row">
<div class="col-md-3 col-xs-12">
<div class="hexagon"></div>
<p class="hexText">Up to 20% increase<br />in sales with<br />Cross sell & Up sell</p>
</div>
<div class="col-md-3 col-xs-12">
<div class="hexagon bgGrey"></div>
<p class="hexText">Up to 35%reduction<br />in print ,postage ,<br />logistic & back<br />office cost</p>
</div>
<div class="col-md-3 col-xs-12">
<div class="hexagon"></div>
<p class="hexText">Scalable100+million <br />statements<br />processed & <br />distributed monthly </p>
</div>
<div class="col-md-3 col-xs-12">
<div class="hexagon bgGrey"></div>
<p class="hexText">Up to 35%reduction<br />in print ,postage ,<br />logistic & back<br />office cost</p>
</div>
</div>