27

I am working on a project that calls for two triangles to hold background images, and be links.

Here is my mock up for how I would like the two triangles.

Triangles with background images

Currently, I have just two divs that span the 900x600 with each triangle as a background image. The issue I am having now is I can't hover over the transparent part of the Cinema div to reach the photo div.

Can I accomplish this design with css3 triangles and set their background images? I always thought the custom shape is made up from a border, with a border-color.

Is it possible to do with css3 triangles, and if so, can someone help me with the code?

Here is what I currently have.

.pageOption {
  position: relative;
  width: 900px;
  height: 600px;
}
.pageOption .photo {
  position: absolute;
  top: 0px;
  left: 0px;
  width: 900px;
  height: 600px;
  background: url('../images/menuPhoto.png') no-repeat 0 0;
}
.pageOption .cinema {
  position: absolute;
  bottom: 0px;
  right: 0px;
  width: 900px;
  height: 600px;
  background: url('../images/menuCinema.png') no-repeat 0 0;
}
<div class="pageOption">
  <a href="#" class="option photo" id="weddingPhoto"></a>
  <a href="#" class="option cinema" id="weddingCinema"></a>
</div>
web-tiki
  • 99,765
  • 32
  • 217
  • 249
Ryan
  • 2,144
  • 8
  • 28
  • 39
  • try css [`pointer-events`](https://developer.mozilla.org/en/CSS/pointer-events) property. – Ram Jun 11 '12 at 12:39

5 Answers5

43

It's really easy if you use child images for the links instead of background images. You just need to skew the two .option elements with different transform origins, then unskew their child images and set overflow: hidden on both .pageOption and the .option elements. Support is good, should work for everything except IE8/7 and Opera Mini.

DEMO

Result:

triangle images

HTML:

<div class='pageOption'>
  <a href='#' class='option' data-inf='photo'>
    <img src='../images/menuPhoto.png'>
  </a>
  <a href='#' class='option' data-inf='cinema'>
    <img src='../images/menuCinema.png'>
  </a>
</div>

Relevant CSS:

.pageOption {
  overflow: hidden;
  position: relative;
  width: 40em; height: 27em;
}
.option, .option img { width: 100%; height: 100%; }
.option {
  overflow: hidden;
  position: absolute;  
  /* arctan(27 / 40) = 34.01935deg 
   * need to skew by 90deg - 34.01935deg = 55.98065deg
  */
  transform: skewX(-55.98deg);
}
.option:first-child {
  left: -.25em;
  transform-origin: 100% 0;
}
.option:last-child {
  right: -.25em;
  transform-origin: 0 100%;
}
.option img {
  transform: skewX(55.98deg);
  transform-origin: inherit;
}
Community
  • 1
  • 1
Ana
  • 35,599
  • 6
  • 80
  • 131
  • 2
    To build on top of Ana's answer, if the container's width needs to be flexible, you can calculate the angle with javascript on window resize as outlined in this answer: http://stackoverflow.com/a/14200600/848254 – Zach Esposito Dec 09 '14 at 19:46
7

You can achive this layout with several approaches. Here is an example using an inline svg and the clip-path element:

<svg viewbox="0 0 10 6.7">
  <defs>
    <clipPath id="top">
      <polygon points="0 0, 9.9 0, 0 6.6" />
    </clipPath>
    <clipPath id="bottom">
      <polygon points="10 0.1, 10 6.7, 0.1 6.7" />
    </clipPath>
  </defs>
  <image xlink:href="http://i.imgur.com/RECDV24.jpg" x="0" y="0" height="6.7" width="10" clip-path="url(#top)"/>
  <image xlink:href="http://i.imgur.com/5NK0H1e.jpg" x="0" y="0" height="6.7" width="10" clip-path="url(#bottom)"/>
</svg>
web-tiki
  • 99,765
  • 32
  • 217
  • 249
4

A responsive idea using CSS clip-path

.pageOption {
  height: 100vh;
  position: relative;
}

.pageOption .photo {
  position: absolute;
  top: 0;
  left: 0;
  right: 5px;
  bottom: 5px;
  background: url('https://picsum.photos/id/1068/900/900') center/cover;
  clip-path: polygon(0 0, 100% 0, 0 100%);
}

.pageOption .cinema {
  position: absolute;
  top: 5px;
  left: 5px;
  right: 0;
  bottom: 0;
  background: url('https://picsum.photos/id/1055/900/900') center/cover;
  clip-path: polygon(100% 100%, 100% 0, 0 100%);
}
.pageOption a:hover {
  filter:grayscale(1);
}

body {
  margin: 0;
}
<div class="pageOption">
  <a href="#" class="option photo" ></a>
  <a href="#" class="option cinema"></a>
</div>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
3

Here are my CSS suggestions:

  1. Using canvas which is HTML5 tag and is not cross browser.
  2. Using SVG. (Most reliable one)
  3. Using CSS3 rotate transition and cover it in a wrapper with hidden overflow. Again is not cross browser.

Rotate transition:

-webkit-transform: rotate(7.5deg);  /* Saf3.1+, Chrome 
   -moz-transform: rotate(7.5deg);  /* FF3.5+ 
    -ms-transform: rotate(7.5deg);  /* IE9 
     -o-transform: rotate(7.5deg);  /* Opera 10.5 
        transform: rotate(7.5deg);
           filter: progid:DXImageTransform.Microsoft.Matrix(/* IE6–IE9 
                   M11=0.9914448613738104, M12=-0.13052619222005157,M21=0.13052619222005157, M22=0.9914448613738104, sizingMethod='auto expand');
Tooraj Jam
  • 1,592
  • 14
  • 27
0

As you said, css3 tringles are made of borders so you can't attach backgrounds to them.

I would suggest you to just to use two PNGs one upon the other and to use js in order listen to the click event and create the correct action based on the mouse position.

There is also a webkit-mask css property but it very unsupported in other browsers (I used it for a little pageing pilling trick - http://jsfiddle.net/xTNTH/3/ - best on safari [no js only css] - http://snag.gy/7fRNq.jpg)

Oren Roth
  • 152
  • 1
  • 11