6

I'm trying to create two elongated hexagons in like:

enter image description here

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.

3
  • 1
    Best solution for your case would be to use SVG. We could have a look at CSS clip-path but the browser support is poor (IE doesn't support it at all, FF needs SVG to be provided as path). Commented Apr 5, 2016 at 9:40
  • You can do too this with JS/JQuery, using the number of char in your string, calculate/set the width of your hexagon. The others features can be implemented in CSS3. But this solution will implicate that you can have one unique id for each hexagon, to set the width... Commented Apr 5, 2016 at 9:41
  • I think that SVG is the best solution, too. I forgot to say that the main devices for my project is Apple iPad. I will update this and also add the tag "svg" Commented Apr 5, 2016 at 9:44

2 Answers 2

7

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.)

Sign up to request clarification or add additional context in comments.

4 Comments

Wow, Version 1 is perfect! Since I'm not familiar with SVG and clip-path: How do I modify the border-width? in my example it should be 7 pixels.
@Crack_David: That should be pretty simple. The top and left of the pseudo-element should be equal to border-width whereas their height and width should be lesser than 100% by 2 times the border-width. This makes the pseudo sit nicely inside the container and thus makes the container's background look like its border.
(Note: Depending on border-width you may have to do an one-time edit of the pseudo's clip-path also. If you see in the demo, the clip on left and right of parent is 15px but on child it is 13px to maintain same thickness throughout. This will unfortunately have to be trial and error and there is no way around this as far as I know.)
Ah, now I get it. Thank you very much!
0
.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>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.