Transparent arrow/triangle indented over an image
There are several approaches to make a transparent arrow over an image with CSS. The two I will describe involve pseudo elements to minimize markup and have the same output. You can also see an SVG approach at the end of this answer :
The transparent effect on the black part arround the arrow is made with rgba()
colors that allow transparency. But you can use opacity on the pseudo elements if you prefer.
1. SkewX()
You can use the CSS3 skewX()
property on two pseudo elements to make the transparent arrow. The main asset of this approach is that the transparent arrow can be responsive but it also allows you to put a border on the black shape and around the traingle.
The responsiveness of the shape is made with the padding-bottom
property to maintain it's aspect ratio (this technique is described here).
DEMO
.wrap { position: relative; overflow: hidden; width: 70%; margin: 0 auto;}.wrap img { width: 100%; height: auto; display: block;}.arrow { position: absolute; bottom: 0; width: 100%; padding-bottom: 3%; background-color: rgba(0, 0, 0, 0.8);}.arrow:before,.arrow:after { content: ''; position: absolute; bottom: 100%; width: 50%; padding-bottom: inherit; background-color: inherit;}.arrow:before { right: 50%; -ms-transform-origin: 100% 100%; -webkit-transform-origin: 100% 100%; transform-origin: 100% 100%; -ms-transform: skewX(45deg); -webkit-transform: skewX(45deg); transform: skewX(45deg);}.arrow:after { left: 50%; -ms-transform-origin: 0 100%; -webkit-transform-origin: 0 100%; transform-origin: 0 100%; -ms-transform: skewX(-45deg); -webkit-transform: skewX(-45deg); transform: skewX(-45deg);}
<div class="wrap"> <img src="https://farm8.staticflickr.com/7187/6895047173_d4b1a0d798.jpg" /> <div class="arrow"></div></div>
Transparent arrow in between 2 sections
There is clip-path property in CSS. Support is not wery good, but it works.
section { width: 300px; height: 200px;}
.first { background: red; -webkit-clip-path: polygon(0% 0%, 100% 0%, 100% 85%, 60% 85%, 50% 100%, 40% 85%, 0 85%); clip-path: polygon(0% 0%, 100% 0%, 100% 85%, 60% 85%, 50% 100%, 40% 85%, 0 85%);}
.second { background: green; margin-top: -30px;}
<section class="first"></section><section class="second"></section>
Inside transparent arrow on the top
As stated in the question, your case is a bit different from the example that was provided by web-tiki. In the example that you were referring to, the border with the transparent cut was included as the bottom border for the image whereas you need it as the top border of the plain text area.
The expected output can be achieved with the same skew
technique described in that answer. However, it needs to be tweaked a bit to match your case.
- First thing is, the skewed pseudo-elements (that produce the border) should be added to the container of plain text area and not the top section which holds the image. This part you have already done correctly.
- Next, you need to position the border such that even with the border the height of your text container will be equal to the other two images placed by its side. For this, you need to position the elements that form the border within the plain text container (
top: 0%
) instead of above it (bottom: 100%
in your code). - Then, if the text container has a non-transparent background, you need to clip it such that it is not present behind the elements that is creating the border effect. This can be achieved by adding a
padding-top
on the text container equal to theheight
of the border pseudo-elements and then settingbackground-clip: content-box
to it. - Finally, you need to move the entire bottom part up by the same number of pixels as the height of the border in order for the top image to be seen through the transparent cut out area. This can be done by adding a negative
margin-top
to the bottom container.
Putting it altogether your code should be similar to the below snippet to achieve the effect that you need. (Note: Your fiddle has way too much code and so I have created a simpler sample for the demo).
.section { height: 200px; width: 500px; background: url(http://lorempixel.com/500/200/nature/3);}.bottom-container { margin-top: -15px; height: 100px; width: 500px;}.text,.middle-image,.right-image { float: left; height: 100%; width: calc(100% / 3);}.middle-image { background: url(http://lorempixel.com/200/100/nature/2);}.right-image { background: url(http://lorempixel.com/250/100/nature/1);}.text { position: relative; box-sizing: border-box; height: 100%; padding-top: 15px; text-align: center; line-height: 85px; background: #F7F7F7; /* Just for demo */ background-clip: content-box; /* needed only if your background is not transparent */ overflow: hidden;}.text:after,.text:before { position: absolute; content: ''; top: 0px; height: 15px; background: rgb(215,182,115);}.text:before { left: 0px; width: 25%; transform-origin: left bottom; transform: skew(45deg);}.text:after { right: 0px; width: 75%; transform-origin: right bottom; transform: skew(-45deg);}
<!-- prefix free library to avoid browser prefixes in CSS --><script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<section class="section"></section><div class="bottom-container"> <div class="text">Some text</div> <div class="middle-image"></div> <div class="right-image"></div></div>
Creating a transparent arrow above image in CSS3
To draw a transparent / inverted triangle in CSS3
you could use the CSS3 triangle technic, and make the inverted shape by combining the :before
and :after
pseudo objects, each to draw one part of the triangle.
You could do something like this:
.image {
position:relative;
height:200px;
width:340px;
background:orange;
}
.image:before, .image:after {
content:'';
position:absolute;
width:0;
border-left:20px solid white;
left:0;
}
.image:before {
top:0;
height:20px;
border-bottom:16px solid transparent;
}
.image:after {
top:36px;
bottom:0;
border-top:16px solid transparent;
}
here is an illustrative jsfiddle
I just used a plane orange background for the example ... but you can change it to image, and you hopefully get what you wanted =)
Edit: and a more final result could then be something like this
Transparent arrow on right side of image
There are two polygons with white background over the image, it is not an arrow but the space between the two polygons. Changin the width and the position of :before
and :after
you can move the triangle.
.wrap { position: relative; overflow: hidden; width: 70%; height:150px; margin: 0 auto; background-color:#fff;}.wrap img { width: 100%; height: auto; display: block;}.wrap:before, .wrap:after { content:''; position: absolute; bottom: 0; width: 100%; background-color: inherit; padding-bottom:3%;}.wrap:before {
-ms-transform-origin: 100% 100%; -webkit-transform-origin: 100% 100%; transform-origin: 100% 100%; -ms-transform: skewX(45deg); -webkit-transform: skewX(45deg); transform: skewX(45deg);}.wrap:after { left: 97%; -ms-transform-origin: 0 100%; -webkit-transform-origin: 0 100%; transform-origin: 0 100%; -ms-transform: skewX(-45deg); -webkit-transform: skewX(-45deg); transform: skewX(-45deg);}
<div class="wrap"> <img src="https://farm8.staticflickr.com/7187/6895047173_d4b1a0d798.jpg" /></div>
Image with cut out transparent triangle
With svg clipPath, it is pretty staightforward. Here is an example :
div { position: relative;}svg { position: absolute; bottom: 0; left: 0; width: 100%; height: auto;}
<div> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed quis enim ultricies, ultricies arcu in, pharetra libero. Cras vel venenatis arcu. Nullam sem massa, semper at mauris a.</p> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed quis enim ultricies, ultricies arcu in, pharetra libero. Cras vel venenatis arcu. Nullam sem massa, semper at mauris a.</p> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed quis enim ultricies, ultricies arcu in, pharetra libero. Cras vel venenatis arcu. Nullam sem massa, semper at mauris a, tempor dictum lorem. Proin sit amet nunc vitae enim tempor rutrum vitae vel sem. Fusce lobortis velit sapien, vitae convallis ipsum ultricies ac. Donec tristique maximus finibus. Pellentesque tortor massa, ultricies quis rhoncus sit amet, luctus ac lorem. Donec eget metus fringilla, dignissim tellus ut, varius lacus. Etiam eu pulvinar est, vitae hendrerit est. Interdum et malesuada fames ac ante ipsum primis in faucibus. Proin tristique congue nisi at tincidunt. Cras sollicitudin tortor nulla, ut euismod diam pulvinar vitae. Fusce accumsan metus eget justo tincidunt porta. Morbi dictum a neque ut blandit.</p> <svg id="svg-defs" viewBox="0 0 100 30"> <defs> <clipPath id="clip-shape"> <polygon points="0 0, 40 0, 50 10, 60 0, 100 0, 100 500, 0 500"></polygon> </clipPath> </defs> <image id="img-1" class="svg-image" width="100" height="50" clip-path="url(#clip-shape)" xlink:href="http://www.strayshots.com/images/Sunset-Cliffs-1.jpg"></image> </svg></div>
How do I make an image fill div with an arrow?
You can do it with the clip-path: polygon()
:
.arrow_box { position: relative; background: #88b7d5; width: 400px; height: 200px; -webkit-clip-path: polygon(0 0, 96% 0, 96% 43%, 100% 50%, 96% 57%, 96% 100%, 0 100%); clip-path: polygon(0 0, 96% 0, 96% 43%, 100% 50%, 96% 57%, 96% 100%, 0 100%);}
.user-image { position: absolute; background-repeat: no-repeat; background-size: cover; width: 100%; height: 100%; background-position: center center; position: relative; object-fit: cover; z-index: 10; -webkit-clip-path: polygon(0 0, 96% 0, 96% 43%, 100% 50%, 96% 57%, 96% 100%, 0 100%); clip-path: polygon(0 0, 96% 0, 96% 43%, 100% 50%, 96% 57%, 96% 100%, 0 100%);}
<div class="arrow_box"> <img src="https://upload.wikimedia.org/wikipedia/commons/3/30/Amazona_aestiva_-upper_body-8a_%281%29.jpg" class="user-image" alt=""></div>
Image with bottom triangle that overlay another image
In the answer you linked to there are 2 approaches that allow the output you are looking for.
If you look under the 4th approach (Tooltip with a triangle over an image.) the technique shown is the same as what facebook uses for tooltips when you hover a name.
Although this approach has a better browser support, I would prefer to use an svg approach (also provided in the post you linked to) with the clipPath
element to make the triangle at the bottom.
Adapted to your use case, it could look like this :
*{margin:0;}svg{ display:block; position:relative; margin-bottom:-3.5%; z-index:50;}svg:nth-child(2){ z-index:49;}svg:nth-child(3){ z-index:48;}
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 600 400"> <defs> <clipPath id="clip"> <path d="M0 0 H600 V380 H320 L300 400 L280 380 H0z" /> </clipPath> </defs> <image xlink:href="http://lorempixel.com/600/400/people/1" width="600" height="400" clip-path="url(#clip)"/></svg><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 600 400"> <image xlink:href="http://lorempixel.com/600/400/nature/1" width="600" height="400" clip-path="url(#clip)"/></svg><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 600 400"> <image xlink:href="http://lorempixel.com/600/400/abstract/6" width="600" height="400" clip-path="url(#clip)"/></svg>
Hollow arrow in front of an image
If you want to minimise and remove all unsemantic markup you can do :
DEMO
This technique relies on pseudo elements and therefore prevents the use of unsemantic markup. Pseudo elements are supported by IE8+ see canIuse. It also needs the box-sizing
property to enable responsive width (box-sizing: border-box
is also supported by IE8+ see canIuse).
HTML :
<div class="wrap">
<img src="http://placekitten.com/800/350" />
<article>
<h1>Hellow World, meow</h1>
</article>
</div>
CSS :
body {
background:#fad;
padding:0;
margin:0;
}
$arrow_width: 20px;
$arrow_height: 20px;
$box_color: #d3d030;
.wrap {
img {
width:100%;
height:auto;
vertical-align:bottom;
}
article{
padding:20px;
background:$box_color;
color:#fff;
position:relative;
}
}
article:before, article:after{
content:'';
position:absolute;
width:50%;
bottom:100%;
box-sizing:border-box;
}
article:before{
left:0;
border-bottom:20px solid #D3D030;
border-right:20px solid transparent;
}
article:after{
right:0;
border-bottom:20px solid #D3D030;
border-left:20px solid transparent;
}
Related Topics
Css Change Button Style After Click
Background Color of Text in Svg
Is Float For Layout Bad? What Should Be Used in Its Place
How to Vertically Align an Image Inside a Div
How to Really Isolate Stylesheets in the Google Chrome Extension
How to Prevent Less from Trying to Compile CSS Calc() Properties
What Exactly Is Device Pixel Ratio
Difference Between Margin and Padding
Add Bootstrap Glyphicon to Input Box
Css Files Are Not Loading in Laravel View
How to Include CSS Files Using Node, Express, and Ejs
Simulate Display: Inline in React Native
Size of Html5 Canvas Via CSS Versus Element Attributes
Media Queries: How to Target Desktop, Tablet, and Mobile
Center a Column Using Twitter Bootstrap 3
Css3 Selector :First-Of-Type With Class Name
Change Bootstrap Navbar Collapse Breakpoint Without Using Less