Last week the project at work proposed a new design feature on where a div has a top shaped like the roof of a house. I knew I couldn't do it as an image, so my first instinct was to use a
:before element with a shaped border to make a shallow triangle, but I realized I had never done a responsive version, it has always been small arrows after text or something along those lines, so that wouldn't work.
Then I recalled reading about CSS Clip Paths which work like Photoshop layer masks. I could add a
:before block and just clip the two top corners off with the path. Should be pretty easy, however I had never worked with clip paths before.
After some searching I found a great tool for generating the clip path, which helped out a lot. It has pre-defined shapes you can use, and it also highlights which value is changing as you manipulate the path points. I set it all up in a sandbox but immediately noticed a small slice between the div and the before element. I tried a -1px bottom margin and it would clip the triangle shape, then when I tried using a border or box shadow, but that still didn't work. See the example below - if you resize the window the line appears and dissapears at certain sizes.
Clip path on a before element
Okay, a before won't work, next step was to apply the clip path on the div itself. I had to add a lot of top padding to offset the cut, but it seems to work pretty well.
Clip path on the element itself
A great way to understand how it works is to think an graph with an X and Y axis. Take your finger and trace the shape you want to cut out, and every time you change direction, those are points on the graph.
clip-path: polygon(50% 0, 100% 25%, 100% 100%, 0 100%, 0 25%);
Using this mental model, we take our finger and place it at the top of the graph, halfway across (50% 0). This corresponds to the tip of the house. Drag your finger to the right to a quarter of the way down, this is the top right corner (100% 25%). Drag it all the way down to the bottom right (100% 100%), then across to the left corner (0 100%), back up to the top left corner (0 25%), and the path will automatically complete itself if you don't close it.
This is supported in most modern browsers, but I'll have to come up with an alternative for IE. There are also options for circular cutouts and even inset frames, but I still need to explore more. Play around with the generator linked above to see what you can come up with.
After playing with this feature on different components I am having some issues. The "pitch" of the roof obviously changes depending on the width of the screen, however the real issue is the overall shape will vary depending on the overall height of the div. So if a module is rather tall, the sides of the 'house' are going to be taller, since it's a percentage of the whole height. Smaller modules will have 'shorter' houses.