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?

Problem courtesy of: zhilevan

Solution

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

Solution courtesy of: chipChocolate.py

Discussion

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.

Discussion courtesy of: Harry

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>

Discussion courtesy of: The Pragmatick

This recipe can be found in it's original form on Stack Over Flow .

我来评几句
登录后评论

已发表评论数()

相关站点

+订阅
热门文章