Outline inside clip-path - css

I'm looking for a way to do this:
https://imgur.com/j7uMWwj.jpg
I add a clip-path to do the shield shape, but I just don't see how I can add this outline following the shape... Outlines or borders just do not follow shapes.
I tried something like this :
.shield_mask{
position: relative;
-webkit-clip-path: polygon(0 0, 100% 0, 100% 90%, 50% 100%, 0 90%);
clip-path: polygon(0 0, 100% 0, 100% 90%, 50% 100%, 0 90%);
&:before{
position: absolute;
background-color: transparent;
top: 12px; /* equal to border thickness */
left: 12px; /* equal to border thickness */
width: 327px; /* container height - (border thickness * 2) */
height: 317px; /* container height - (border thickness * 2) */
-webkit-clip-path: polygon(0 0, 100% 0, 100% 90%, 50% 100%, 0 90%);
clip-path: polygon(0 0, 100% 0, 100% 90%, 50% 100%, 0 90%);
-webkit-box-shadow:inset 1px 1px 0 0 #FFF;
box-shadow:inset 1px 1px 0 0 #FFF;
}
}
Not working... I tried with gradients too...
Does anyone have an idea ?

As you noted in your question, borders and outlines do not follow the clip-path outline. This is by design: " A clipping path is conceptually equivalent to a custom viewport for the referencing element. Thus, it affects the rendering of an element, but not the element's inherent geometry. The bounding box of a clipped element (meaning, an element which references a element via a clip-path property, or a child of the referencing element) must remain the same as if it were not clipped." -- developer.mozilla.org/en-US/docs/Web/SVG/Element/clipPath
I don't believe it's possible to accomplish this with CSS alone. But it is possible to do it with CSS and SVG. It's a bit manual and fiddly, but essentially you would need to create an SVG that mimics the inset border you're after and overlay it as a pseudo element on a div with a background image.
Not at all what you were trying to do, but it visually mimics the look you're after.
Hopefully, another contributor will wow us with some CSS wizardry, but until then, if you just really need to get it coded, you can try something like the following...
HTML
<div class="shield_mask" style="background-image: url(http:placehold.it/200x300)" " alt=" ">
</div>
CSS
.shield_mask {
width: 200px;
height: 300px;
display: block;
position: relative;
-webkit-clip-path: polygon(0 0, 100% 0, 100% 90%, 50% 100%, 0 90%);
clip-path: polygon(0 0, 100% 0, 100% 90%, 50% 100%, 0 90%);
}
.shield_mask::after {
content: "";
height: 100%;
width: 100%;
display: block;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-image: url("data:image/svg+xml,%3Csvg width='200' height='300' viewBox='0 0 200 300' fill='none' xmlns='http://www.w3.org/2000/svg'%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M12 13H188V259.233L103.01 286.045L12 259.248V13ZM14 15V257.752L102.99 283.955L186 257.767V15H14Z' fill='white'/%3E %3C/svg%3E ");
z-index: 1000;
background-repeat: no-repeat;
}
See codepen here: https://codepen.io/anon/pen/KYavGq

Related

How to implement special button shape in css [duplicate]

This question already has answers here:
Cut Corners using CSS
(16 answers)
Closed 6 months ago.
I would like to create a button with a special shape (border) like the attached image. Is that even possible with css?
I tried to replicate this button but there are some issues with it:
I have used clip-path property to draw a custom border for the button, however, you have to mention the height and width properties separately or instead just let it span the default length, i.e. it's container dimensions but I had to mention height and width properties due to the reason in the following points
Thanks to this answer for a similar problem of adding border to a clipped path element, which states that it's not possible to add a border to a clipped path because the border is applied to the original rectangle (or square) container before the clip-path is applied and so, it also gets clipped out. I used the solution that's mentioned in that answer, which is use a div as the background of this button with slightly bigger dimensions with the same clipped path but of different color which acts as a border to the button
Finally, I had to mention the dimensions of the parent div which acts as a background so that I could know the exact values of the dimension of the container and hence I could use them to know how much height and width should the button have
div {
display: inline-block;
position: relative;
background: red;
-webkit-clip-path: polygon(100% 0, 100% 81%, 82% 100%, 0 100%, 0 0);
clip-path: polygon(100% 0, 100% 81%, 82% 100%, 0 100%, 0 0);
height: 60px;
width: 140px;
}
button {
position: absolute;
top: 2px;
left: 2px;
height: 56px;
width: 136px;
-webkit-clip-path: polygon(100% 0, 100% 81%, 82% 100%, 0 100%, 0 0);
clip-path: polygon(100% 0, 100% 81%, 82% 100%, 0 100%, 0 0);
font-size: 20px;
text-align: center;
color: white;
background: pink;
border: none;
}
<div class="btn_bg">
<button>Certified?<br>Let us know</button>
</div>
you can use this code with clip-path
.outside {
position: relative;
width: 70vmin;
height: 23vmin;
background: tomato;
clip-path: polygon(85% 0%, 85% 68%, 68% 100%, 0% 100%, 0% 78%, 0% 0%, 0% 0%);
}
.inside {
position: absolute;
top: 4px;
left: 4px;
right: 4px;
bottom: 4px;
background: white;
clip-path: polygon(85% 0%, 85% 68%, 68% 100%, 0% 100%, 0% 78%, 0% 0%, 0% 0%);
border:none;
}
<div class="outside">
<button class="inside">
</button>
</div>

How to css rotate with an angle depending on viewport size

I'm trying to define a rotation of an element depending on viewport width in CSS.
Here with a "hard" "transform: rotate(-3.4deg);" :
https://i.postimg.cc/3NqY2Hzy/rotate-1.jpg
I'd like here more angle on smaller viewport width :
https://i.postimg.cc/SQHKX64g/rotate-2.jpg
I tried things like calc(12deg * 5vw) (and any other viewport's size variables units) but none seem compatible with an angle unit.
I could do it in javascript but I'm afraid it would show a bad glitch at page loading on slow computers / connections. I would like to avoid touching to top and bottom dividers, they are generated by a wordpress' theme.
Edit : The element I'm trying to dynamically rotate is the one containing the 3 texts.
If you forget angles but turn to using clip-path you can have a couple of pseudo elements on your element which have backgrounds one of darker and one of lighter green.
As the clip-paths are defined in terms of the percentage amounts rather than actual angles they automatically adjust to different viewports without the need for media queries:
div {
position: relative;
width: 100vw;
height: 30vw;
display: inline-block;
}
div::before,
div::after {
content: '';
position: absolute;
display: inline-block;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
div::before {
z-index: -2;
background-color: lightgreen;
clip-path: polygon(0 0, 100% 0%, 0 35%, 0 100%, 100% 70%, 100% 95%, 0 100%);
}
div::after {
z-index: -1;
background-color: green;
clip-path: polygon(0 0, 100% 0, 0 25%, 0 100%, 100% 75%, 100% 100%, 0 100%);
}
<div></div>

Adding triangles with CSS that are responsive

I am struggling to create the above design of the green background, two white triangles and blue dots on the point of the triangles.
I have to create two triangles using W3School tutorial but they are not responsive causing issues. I have created the green background in PS with white triangles and blue dots but cannot get the image to sit in the same position across screen sizes.
Any help in creating the above using HTML/CSS would be great.
You can use clip-path on a pseudo element to create the graph-like zig zag and background images on another pseudo element to place the blue dots.
It is important to note that everything has to be done in relative terms, e.g. %s, so that the whole is responsive.
While this is pretty straightforward for the zig zag, adjustments have to be made to the placing of the dots as things are placed relative to their top left corner not relative to their center, which is what we require for the circles.
Also the height of the 'background' (the zigzag plus a little bit below the green to accomodate the circle at the bottom) has to be specified in terms of the width. Eventually CSS aspect-ratio will be useful for this but just at the moment not all browsers support it so this snippet uses the well-known hack of defining an element's height in terms of padding (the units for which are always the width's).
* {
padding: 0;
margin: 0;
}
.graphbg {
background: white;
width: 100vw;
height: 100vh;
position: relative;
margin: 0;
padding: 0;
}
.graphbg::before,
.graphbg::after {
margin: 0;
padding: 0;
box-sizing: border-box;
overflow: hidden;
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
z-index: 1;
overflow: hidden;
--w: 4;
/* set these so --w/--h is the proportion of width to height you want this background to have */
--h: 1;
/* soon you will be able to use aspect-ratio: 4 / 1 but currently, August 2021, Safari IOS does not support it */
height: 0;
padding-top: calc( var(--h) / var(--w) * 100%);
/* to force the element to have the right height */
}
.graphbg::before {
background: green;
clip-path: polygon(0 0, 98% 0, 50% 95%, 25% 50%, 0 95%);
}
.graphbg::after {
background-image: radial-gradient(circle, blue 0 70%, transparent 70% 100%), radial-gradient(circle, blue 0 70%, transparent 70% 100%), radial-gradient(blue 0 70%, transparent 70% 100%), radial-gradient(blue 0 70%, transparent 70% 100%);
background-repeat: no-repeat;
background-size: 2% 8%;
background-position: -1% 99%, 24.5% 50%, 50% 97%, 99% -4%;
}
<div class="graphbg"></div>

Is it possible to generate a box-shadow that follows the shape of a clip-path polygon?

Let's say I have this clip path (a triangle generated here)
-webkit-clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
Is it possible to create a box-shadow from this clip path?
Something like this:
box-shadow: 20px 25px 50px -25px #000;
You can use a filter on the containing div, try:
.container {
filter: drop-shadow(0px 10px 5px rgba(0,0,0,0.1))
}
eg: https://plnkr.co/edit/kePuv7OLQwawPjiBLg3J?p=preview
I'm assuming you mean, is it possible to create the shadow along the polygon. If so, then no. box-shadow is unfortunately only a "box", so it can't follow the clip path. It'd still apply to the rectangle of the element itself.
You could however pair it with another element that has the same clipping, but is set below it and offset and create a pseudo-shadow:
#box {
position: relative;
width: 200px;
height: 200px;
}
#content {
width: 100%;
height: 100%;
background: #3CF;
-webkit-clip-path: polygon(0 100%, 0 0, 100% 0, 80% 100%);
}
#shadow {
position: absolute;
z-index: -1;
content: "";
background: rgba(0, 0, 0, .5);
width: 200px;
height: 200px;
left: 5px;
top: 5px;
-webkit-clip-path: polygon(0 100%, 0 0, 100% 0, 80% 100%);
}
<div id="box">
<div id="content"></div>
<div id="shadow"></div>
</div>
Depending on your use-case, with some clever use of a background image, multiple borders, and/or gradients, you could make the background look between with a fading shadow and what not.
It's not possible, I think. I would suggest you this work around.
.triangle {
font-size:100px;
color:blue;
text-shadow:0 0 10px black;
}
<span class="triangle">▲</span>

Making jagged triangle border in CSS

I have a shape with an edge like this in Photoshop:
Is it possible to make the repeated triangles as a border with CSS?
You can use gradients to create a zig-zag patterned background, use the ::after pseud-element to apply it like a border.
.header{
color: white;
background-color: #2B3A48;
text-align: center;
}
.header::after {
content: " ";
display: block;
position: relative;
top: 0px;
left: 0px;
width: 100%;
height: 36px;
background: linear-gradient(#2B3A48 0%, transparent 0%), linear-gradient(135deg, #272220 33.33%, transparent 33.33%) 0 0%, #272220 linear-gradient(45deg, #272220 33.33%, #2B3A48 33.33%) 0 0%;
background-repeat: repeat-x;
background-size: 0px 100%, 9px 27px, 9px 27px;
}
<div class="header"><h1>This is a header</h1></div>
Source: CSS Zigzag Border with a Textured Background
JSFiddle: http://jsfiddle.net/kA4zK/
For future viewers, I found this adaptation of #extramaster's answer to be a little simpler.
It's essentially the same, but it uses one fewer background gradients and allows the backing object (.navbar in my markup) to show through instead of hard-coding the second color into the zig-zag.
JsFiddle: http://jsfiddle.net/861gjx0b/2/
.header {
position: relative;
color: white;
background-color: #2B3A48;
text-align: center;
}
.navbar {
background: #272220;
height: 20px;
}
.header:after {
content: "";
position: absolute;
display: block;
height: 10px;
bottom: -10px;
/* -height */
left: 0;
right: 0;
/* TODO Add browser prefixes */
background: linear-gradient( 45deg, transparent 33.333%, #2B3A48 33.333%, #2B3A48 66.667%, transparent 66.667%), linear-gradient( -45deg, transparent 33.333%, #2B3A48 33.333%, #2B3A48 66.667%, transparent 66.667%);
background-size: 8px 20px;
/* toothSize doubleHeight */
background-position: 0 -10px;
/* horizontalOffset -height */
}
<div class="header">
<h1>This is a header</h1>
</div>
<nav class="navbar"></nav>
Personally, I think clip-path is easier to work with/understand than complex background gradients.
body {
font-family:Roboto,'Open Sans',Helvetica,sans-serif;
}
.container {
background:#ddd;
margin:0 auto;
max-width:800px;
padding:30px;
}
h1:first-child {margin:0;}
.jagged-bottom {
position:relative;
}
.jagged-bottom:after {
background:#ddd;
content:"";
height:2vw;
position:absolute;
top:100%;
left:0;
right:0;
clip-path:polygon(
0 0, 2.5% 100%, 5% 0, 7.5% 100%,
10% 0,12.5% 100%,15% 0, 17.5% 100%,
20% 0,22.5% 100%,25% 0, 27.5% 100%,
30% 0,32.5% 100%,35% 0, 37.5% 100%,
40% 0,42.5% 100%,45% 0, 47.5% 100%,
50% 0,52.5% 100%,55% 0, 57.5% 100%,
60% 0,62.5% 100%,65% 0, 67.5% 100%,
70% 0,72.5% 100%,75% 0, 77.5% 100%,
80% 0,82.5% 100%,85% 0, 87.5% 100%,
90% 0,92.5% 100%,95% 0, 97.5% 100%, 100% 0);
}
<div class="container jagged-bottom">
<h1>Looks Like A Receipt</h1>
<p>Simply adjust the clip path on the pseudo-element if you want more or fewer spikes, and the height if you want them to be taller or shorter.</p>
</div>
There is a border-image property in CSS3.
Maybe you can work it out in a way you want. More here:
https://developer.mozilla.org/en-US/docs/Web/CSS/border-image
Or here
https://www.w3schools.com/cssref/css3_pr_border-image.asp
You can create an individual triangle using CSS quite easily (just tweak border properties). In order for this to work you will need to generate quite a bit of markup yourself. I would recommend against this approach.
Instead you are likely better off using an individual image containing a single triangle (preferably a transparent .png) and then use background-image and background-repeat (repeat-x) properties to bind that to a div (your "border").
Unfortunately there is no yet a straight-forward way to achieve this using pure CSS.

Resources