Clipping and Masking a div using CSS without Image - html

I am trying to clip a triangle inside a div .box-inner-2 and mask the outside of that to look like:
but what I am getting now is this. Can you please let me know how to do this?
.wrapper{
position: relative;
height: 250px;
width: 250px;
}
.box-inner-1{
position: absolute;
top:0;
left: 0;
right: 0;
bottom: 0;
background-color: red;
}
.box-inner-2{
position: absolute;
top:0;
left: 0;
right: 0;
bottom: 0;
background-color: white;
clip-path: polygon(10% 0, 0 20%, 20% 20%);
}
<div class="wrapper">
<div class="box-inner-1"></div>
<div class="box-inner-2"></div>
</div>

So here is a brief of what I changed in your code:
Moved the triangle clip-path: polygon(10% 0, 0 20%, 20% 20%) to the box-inner-1 (adjusted top and left for illustration)
Added an inset clip-path to the box-inner-2 and a psuedo after element to clip the triangle.
See demo below:
.wrapper {
position: relative;
height: 250px;
width: 250px;
border: 2px solid;
}
.wrapper:after {
content: '';
clip-path: inset(0% 94% 0% 0%);
background: #fff;
display: block;
height: 100%;
}
.box-inner-1 {
position: absolute;
top: 10px;
left: 10px;
right: 0;
bottom: 0;
background-color: red;
clip-path: polygon(10% 0, 0 20%, 20% 20%);
}
.box-inner-2 {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #fff;
clip-path: inset(0% 0% 93% 0%);
}
<div class="wrapper">
<div class="box-inner-1"></div>
<div class="box-inner-2"></div>
</div>

Related

gear icon using a single div in pure css

I'm trying to create this icon using pure css & a single div
so far I've only managed to add 2 points like this:
:root {
--gear_radius: 5rem;
--gear_color: black;
--gear_thickness: 1.5rem;
--gear_pin_length: 1.5rem;
--gear_pin_gap: 1.5rem;
}
.gear {
margin: 5rem;
height: var(--gear_radius);
width: var(--gear_radius);
border-radius: 50%;
border: var(--gear_color) var(--gear_thickness) solid;
box-sizing: border-box;
position: relative;
}
.gear:before {
position: absolute;
content: "";
display: block;
height: var(--gear_pin_length);
width: var(--gear_thickness);
left: 50%;
top: 50%;
transform: translate(-50%, -50%) rotate(45deg);
box-shadow: 0 calc(var(--gear_thickness) * 2) 0 0 black, 0 calc(var(--gear_thickness) * -2) 0 0 black;
}
.gear:after {
position: absolute;
content: "";
display: block;
height: var(--gear_pin_length);
width: var(--gear_thickness);
left: 50%;
top: 50%;
transform: translate(-50%, -50%) rotate(-45deg);
box-shadow: 0 calc(var(--gear_thickness) * 2) 0 0 black, 0 calc(var(--gear_thickness) * -2) 0 0 black;
}
<div class="gear"></div>
How do I add 2 more points at the top and bottom? I don't know what approach to take from here?
The original picture of a gear wheel has an angle to the sides of each tooth.
However, I notice that in your part-solution you aren't worried about that and have parallel edges.
Here's a snippet that puts in all 6 teeth with parallel edges.
It uses before and after pseudo elements which had stripes as background and are rotated. The main div also has a stripe for a background but additionally a radial gradient with white and black circles.
.cog {
width: 30vmin;
height: 30vmin;
position: relative;
background-image: radial-gradient(white 0 35%, black 35% 70%, transparent 70% 100%), linear-gradient(to right, black, black);
background-size: 70% 70%, 25% 100%;
}
.cog::before,
.cog::after {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: linear-gradient(to right, black, black);
background-size: 25% 100%;
z-index: -1;
}
.cog,
.cog::before,
.cog::after {
background-repeat: no-repeat;
background-position: center center;
transform-origin: center;
}
.cog::before {
transform: rotate(60deg);
}
.cog::after {
transform: rotate(120deg);
}
<div class="cog"></div>
Here's what it produces:
To get more sophisticated shape - such as the slope on the teeth, you could do more with gradients or just CSS clip-path (though by the time you've done this you probably might as well have created an SVG).
Well, of course SVG is better, but since your question is more of a challenge, here is my solution:
* {
margin: 0;
padding: 0;
}
.icon {
position: relative;
background: beige;
height: 160px;
width: 160px;
}
.wheel {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
width: 32px;
height: 32px;
background: beige;
border-radius: 50%;
border: solid 24px brown;
}
.cog {
position: absolute;
width: 24px;
height: 120px;
border-radius: 6px;
background: brown;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
}
.cog:nth-child(2) {
transform: rotate(45deg);
}
.cog:nth-child(3) {
transform: rotate(90deg)
}
.cog:nth-child(4) {
transform: rotate(135deg)
}
<div class="icon">
<div class="cogs">
<div class="cog"></div>
<div class="cog"></div>
<div class="cog"></div>
<div class="cog"></div>
</div>
<div class="wheel"></div>
<div>

Add semi circle curve for a div at left and right using background color - CSS [duplicate]

This question already has answers here:
CSS Cut out circle from a rectangular shape
(3 answers)
Closed 1 year ago.
Can anyone help me with how to get the style like in the image attached below using background colour for a div? I tried adding using pseudo-classes before and after but doesn't seem to be coming through.
.card {
height: 190px;
background: #070B32;
width: 360px;
position: relative;
}
.card:before {
background: #070B32;
position: absolute;
content: "";
left: 0;
height: 50px;
border-radius: 50% 50% 0 0;
}
.card:after {
background: #070B32;
position: absolute;
content: "";
right: 0;
height: 50px;
border-radius: 50% 50% 0 0;
}
<div class="card">
</div>
Use width top values too to have semi-circles with a change in color
.card {
height: 190px;
background: #070B32;
width: 360px;
position: relative;
}
.card:before {
background: white;
position: absolute;
content: "";
left: 0;
top:35%;
width: 25px;
height: 50px;
border-radius: 0 150px 150px 0;
}
.card:after {
background: white;
position: absolute;
content: "";
right: 0;
top:35%;
width: 25px;
height: 50px;
border-radius: 150px 0 0 150px;
}
<div class="card">
</div>
Update:
div {
height: 150px;
margin: 5em 2em;
background: radial-gradient(circle at left center, transparent, transparent 30px, #070B32 30px, transparent), radial-gradient(circle at right center, transparent, transparent 30px, #070B32 30px, transparent);
border-radius: 8px;
position: relative;
width: 360px;
margin: auto;
}
body {
background-image: url(http://www.fillmurray.com/1000/1000);
background-size: cover;
}
<div>
</div>
you should use width: 50px, background-color: white;
and responsive vertical alignment:
top: 50%; transform: translateY(-50%);
.card {
height: 190px;
background: #070B32;
width: 360px;
position: relative;
}
.card:before {
background: #ffffff;
position: absolute;
content: "";
left: -25px;
top: 50%;
transform: translateY(-50%);
height: 50px;
width: 50px;
border-radius: 50%;
}
.card:after {
background: #ffffff;
position: absolute;
content: "";
right: -25px;
top: 50%;
transform: translateY(-50%);
height: 50px;
width: 50px;
border-radius: 50%;
}
<div class="card">
</div>
Or just use a background.
.card {
--circle-color: #fff;
--circle-size: 50px;
background: radial-gradient(farthest-side circle, var(--circle-color) 97%, transparent) calc(100% + (var(--circle-size) / 2)) 50% / var(--circle-size) var(--circle-size),
radial-gradient(farthest-side circle, var(--circle-color) 97%, transparent) calc(var(--circle-size) / -2) 50% / var(--circle-size) var(--circle-size),
#070B32;
background-repeat: no-repeat;
height: 190px;
width: 360px;
}
<div class="card">
</div>

How to make responsive to element triangle shape?

I want background shape to include triangle shape and I did it with css. I want that to be responsive in every screen size. I am stuck in this . Any advice ...
header {
width: 100%;
height:150px;
background: #eee;
}
main {
width: 100%;
height:150px;
background: #000;
position:relative;
z-index: 1;
}
main::before {
background: inherit;
top: 0;
content: '';
display: block;
height: 90%;
left: 0;
position: absolute;
right: 0;
transform: skewY(-3deg);
transform-origin: 0;
z-index: -1;
}
main::after {
border-top: 16vh solid blue;
border-left: 50vw solid transparent;
width: 0;
height: 0;
transform: skewY(-3deg);
position: absolute;
content: "";
transform-origin: 0;
right: 0;
top: -10%;
}
<header></header>
<main>
<main>
Expected result in every screen size
You can use clip-path - polygon properties for this.
The issue is, this doesn't support on IE 🤷‍♂️
More information
Mozilla: https://developer.mozilla.org/en-US/docs/Web/CSS/clip-path
W3Schools: https://www.w3schools.com/cssref/css3_pr_clip-path.asp
CSS Tricks: https://css-tricks.com/almanac/properties/c/clip-path/
main {
position: relative;
width: 100%;
height: 150px;
background: #000;
z-index: 1;
overflow: hidden;
}
main::before,
main::after {
content: '';
position: absolute;
display: block;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: 0;
padding: 0;
width: 100%;
height: 100%;
overflow: hidden;
z-index: 0;
}
main::before {
background-color: #00f;
-webkit-clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 0%);
clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 0%);
}
main::after {
background-color: #fff;
-webkit-clip-path: polygon(0 0, 100% 0, 100% 75%, 0 100%);
clip-path: polygon(0 0, 100% 0, 100% 75%, 0 100%);
}
<main><main>
You can try like below:
html::before {
content: "";
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 60vh;
transform-origin: right;
transform: skewY(-5deg);
background: linear-gradient(-160deg, blue 15vw, #000 15.2vw);
}
I really dont want to answer my own question though, I have been research for about two days and I found something really effective solution. So let me post it .
If I have modify a little bit on main::after property , it can be show responsively now.
transform-origin: 0; to transform-origin: -99%;
top: -10% to top: 0
That is...

Dynamically aligning :after according to parent length

http://jsfiddle.net/VpW5x/1141/
.one-line {
position: relative;
}
.one-line:after {
content: '';
position: absolute;
top: 0;
bottom: 0;
width: 25px;
background: red;
clip-path: polygon(100% 50%, 0 0, 0 100%);
left: 100%;
}
How to make the right arrow appear after the text, even if the text is really long like in the example?
use this css will help you
.one-line {
position: relative;
display:inline-block;
vertical-align:top;
}
.one-line:after {
content: '';
position: absolute;
top: 0;
bottom: 0;
width: 25px;
background: red;
clip-path: polygon(100% 50%, 0 0, 0 100%);
left: 100%;
}

How do I give a CSS octagon shape a full border?

I am trying to take this css Octagon and give it a solid red border. However, when i add the border it only works on portion of the shape. Does anyone have a solution for this?
Here is a JS FIDDLE
HTML
<div class='octagonWrap'>
<div class='octagon'></div>
</div>
CSS
.octagonWrap{
width:200px;
height:200px;
float: left;
position: relative;
}
.octagon{
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
overflow: hidden;
}
.octagon:before {
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
transform: rotate(45deg);
background: #777;
content: '';
border: 3px solid red;
}
You can modify your own code to work with this. Right now, you have rules for .octagon that should be for .octagon-wrapper, and rules for .octagon::before that should be for .octagon. Just shift the CSS rules and have them apply to their parents, while changing the border property of .octagon::before to inherit from .octagon.
.octagonWrap {
width:200px;
height:200px;
float: left;
position: relative;
overflow: hidden;
}
.octagon {
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
overflow: hidden;
transform: rotate(45deg);
background: #777;
border: 3px solid red;
}
.octagon:before {
position: absolute;
/* There needs to be a negative value here to cancel
* out the width of the border. It's currently -3px,
* but if the border were 5px, then it'd be -5px.
*/
top: -3px; right: -3px; bottom: -3px; left: -3px;
transform: rotate(45deg);
content: '';
border: inherit;
}
<div class='octagonWrap'>
<div class='octagon'></div>
</div>
SVG solution
I do not know if using svg is an option,
If it is here is how simple it is done.
<svg viewBox="0 0 75 75" width="200px">
<path d="m5,22 18,-18 28,0 18,18 0,28 -18,18, -28,0 -18,-18z" stroke="red" stroke-width="2" fill="black" />
</svg>
You could use an online calculator (or calculate it manually) to compute the size in which the ratio of the side, and overall height needs to be.
Then by using some pseudos and a span element, you could create this shape via:
.oct {
height: 241px;
width: 100px;
background: none;
position: relative;
-webkit-box-sizing: border-box;
box-sizing: border-box;
border-top: 10px solid tomato;
border-bottom: 10px solid tomato;
margin: 100px auto;
transition: all 0.8s;
}
.oct:before,
.oct:after,
.oct span {
content: "";
position: absolute;
height: inherit;
width: inherit;
background: inherit;
-webkit-box-sizing: inherit;
box-sizing: inherit;
border: inherit;
top: -10px;
z-index:-1;
}
.oct:before {
left: -100%;
transform: rotate(-45deg);
transform-origin: top right;
}
.oct:after {
left: 100%;
transform: rotate(45deg);
transform-origin: top left;
}
.oct span {
height: inherit;
width: inherit;
background: inherit;
transform: rotate(90deg);
}
.oct:hover {
transform: rotate(180deg);
}
<div class="oct">
<span></span>
</div>
You can do that very effectively with clip-path
.octagonWrap {
background: red;
width: 200px;
height: 200px;
position: absolute;
-webkit-clip-path: polygon(30% 0%, 70% 0%, 100% 30%, 100% 70%, 70% 100%, 30% 100%, 0% 70%, 0% 30%);
clip-path: polygon(30% 0%, 70% 0%, 100% 30%, 100% 70%, 70% 100%, 30% 100%, 0% 70%, 0% 30%);
}
.octagon {
position: relative;
background: gray;
width: 190px;
height: 190px;
top: 5px;
left: 5px;
-webkit-clip-path: polygon(30% 0%, 70% 0%, 100% 30%, 100% 70%, 70% 100%, 30% 100%, 0% 70%, 0% 30%);
clip-path: polygon(30% 0%, 70% 0%, 100% 30%, 100% 70%, 70% 100%, 30% 100%, 0% 70%, 0% 30%);
}
<div class="octagonWrap">
<div class='octagon'></div>
</div>
Imagine those red lines extending until they touch each other. That square (rotated 45%) has a complete border, you just don't see the "cut off" corners due to the overflow: hidden;
This seems to work (but does so by adding two extra divs, so there may be a better way):
<div class='octagonWrap'>
<div class='octagon'></div>
<div class='vert'> </div>
<div class='hort'> </div>
</div>
and then add tihs css:
.vert {
position: absolute;
left: 60px;
border-top: 3px solid red;
border-bottom: 3px solid red;
height: 194px;
width: 80px;
}
.hort {
position: absolute;
top: 60px;
border-left: 3px solid red;
border-right: 3px solid red;
width: 94px;
height: 80px;
}
You should try using the HTML5 canvas element. You should be able to draw the polygon and then add a stroke to it.