Style an iframe's wrapper div without css clip-path - javascript

I want to find a replacement for CSS's clip-path to assure cross-browser compatibility with internet explorer, edge and safari for the following issue.
The following example shows what I want to do, an iframe component wrapped in a style div with variable border size:
I was able to somewhat replicate this style with clip-path using rotated squares at the cutted out corners and removed the "excess" square with clip-path as you can see in the following image of my component:
The problem arises when I test this component in internet edge, since the latter does not have support to clip-path the squares are never clipped and it appears as so:
As you can verify my styled wrapper is not even similar to the original example, also it does not work in all browsers...
So I am asking for some guidance in what I can do to make this styled div wrapper be supported in all browsers and be somewhat more similar to the original example.
I have read this can be done with :before and :after div compositions but that does not allow me to completely wrap the iframe component. Also, I have read about svg masking which can not also be used due the reason of the former.
Any help is appreciated.
.preview {
width: calc(100vw / 20);
height: calc(100vh / 10);
background: rgba(83, 80, 131, 0.5);
cursor: pointer;
clip-path: polygon( 10px 0%, 100% 0%, 100% 0%, 100% calc(100% - 10px), calc(100% - 10px) 100%, 0% 100%, 0% 100%, 0% 10px);
}
.border-corner {
transition: all 0.2s ease-in;
background: #e9f396;
transform: rotate(45deg);
bottom: -15;
right: -15;
width: 30px;
height: 30px;
position: absolute;
}
<div class="preview center">
<img class="image" src="https://static.independent.co.uk/s3fs-public/thumbnails/image/2017/09/12/11/naturo-monkey-selfie.jpg?w968" />
</div>
<div class="border-corner"></div>

You can consider a pseudo element over the iframe that you style using multiple background:
.box {
display:inline-block;
background:blue;
position:relative;
}
.box:before {
content:"";
position:absolute;
top:20px;
left:20px;
bottom:20px;
right:20px;
background:
/*top left corner*/
linear-gradient(to top left ,transparent 49.8%,blue 50%) top left/30px 30px,
linear-gradient(to top left ,transparent 49.8%,grey 50%) top left/37px 37px,
/*bottom right corner*/
linear-gradient(to bottom right,transparent 49.8%,blue 50%) bottom right/30px 30px,
linear-gradient(to bottom right,transparent 49.8%,grey 50%) bottom right/50px 50px,
/*borders*/
linear-gradient(grey,grey) top /100% 5px,
linear-gradient(grey,grey) bottom /100% 5px,
linear-gradient(grey,grey) right /5px 100%,
linear-gradient(grey,grey) left /5px 100%;
background-repeat:no-repeat;
}
iframe {
display:block;
margin:20px;
background:red;
border:none;
}
<div class="box">
<iframe scr=""></iframe>
</div>

If you can use mask, you can get a CSS only solution. Please note: That excludes IE 10 and IE 11 and it only works in Edge 18+ (partially).
caniuse.com
However, without clip-path or mask, I highly doubt you will find a solution which makes it look equal in every browser while also allowing you to see what's in the background (assuming you want that element to be "floating" via absolute positioning or something alike). For non-supporting browsers, maybe you should consider having a "simple" box.
.shape {
position: relative;
width: 200px;
height: 200px;
background: #c00;
box-shadow: 0 0 0 5px #000 inset;
overflow: hidden;
-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='47' height='49'%3E%3Cpath d='M11.23 0L0 11.23V49h35.77L47 37.77V0H11.23z'/%3E%3C/svg%3E") 0 0/200px 200px;
mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='47' height='49'%3E%3Cpath d='M11.23 0L0 11.23V49h35.77L47 37.77V0H11.23z'/%3E%3C/svg%3E") 0 0/200px 200px;
}
.shape:before,
.shape:after {
content: '';
display: block;
position: absolute;
}
.shape:before {
top: 0;
left: 0;
border-style: solid;
border-width: 55px 55px 0 0;
border-color: #000 transparent transparent transparent;
}
.shape:after {
bottom: 0;
right: 0;
border-style: solid;
border-width: 0 0 70px 70px;
border-color: transparent transparent #000 transparent;
}
.shape_content {
display: block;
width: 100%;
height: 100%;
border: 0 none;
}
<div class="shape">
<iframe src="#foo" class="shape_content"></iframe>
</div>

Related

Add blurred edges to a div but keep the content inside transparent

I have a slider, I want the edges of the content div to have a blur effect, blurring the background image behind it. The background image is from the parent div. As you can see the content inside it is not blurred and you can see through the background, but the edges are blurred. Any ideas on how to achieve this effect?
It doesn't matter if it's CSS only or mixed with JavaScript, I'm using React anyways.
Here's an approach using clip-path (documentation) and backdrop-filter (documentation) Both are relatively new rules, so check your browser compatibility.
We use the clip path to select a 10% "frame" around the inside of your box, and then apply a 10px blur with backdrop-filter
body {
min-height: 100%;
background-image: url('https://i.picsum.photos/id/502/1000/1000.jpg?hmac=L-KRcO3K2TOyaVRnDSO13QrAo73FnHrIBApbvfakTOw')
}
.box {
position: relative;
width: 300px;
height: 300px;
margin: 30px 100px;
}
.frame {
position: absolute;
width: 100%;
height: 100%;
clip-path: polygon(0% 0%, 0% 100%, 10% 100%, 10% 10%, 90% 10%, 90% 90%, 10% 90%, 10% 100%, 100% 100%, 100% 0%);
backdrop-filter: blur(10px);
}
.content {
position: absolute;
border: 1px #fff solid;
top: 10%;
left: 10%;
right: 10%;
bottom: 10%;
}
<div class="box">
<div class="frame"></div>
<div class="content"> Your text here</div>
</div>
Here's a version using CSS variables so you can quickly/easily adjust the blurred border thickness. Just change the --b CSS variable:
body {
min-height: 100%;
background-image: url('https://i.picsum.photos/id/502/1000/1000.jpg?hmac=L-KRcO3K2TOyaVRnDSO13QrAo73FnHrIBApbvfakTOw')
}
.box {
/* The border thickness (Can be a percentage or pixel value) */
--b: 6px;
/* Work out the inverse value for the right/bottom sides of the clip path */
--b2: calc(100% - var(--b));
position: relative;
width: 300px;
height: 300px;
margin: 30px 100px;
}
.frame {
position: absolute;
width: 100%;
height: 100%;
clip-path: polygon(0% 0%, 0% 100%, var(--b) 100%, var(--b) var(--b), var(--b2) var(--b), var(--b2) var(--b2), var(--b) var(--b2), var(--b) 100%, 100% 100%, 100% 0%);
backdrop-filter: blur(10px);
}
.content {
position: absolute;
border: 1px #fff solid;
top: var(--b);
left: var(--b);
right: var(--b);
bottom: var(--b);
}
<div class="box">
<div class="frame"></div>
<div class="content"> Your text here</div>
</div>
You don't need to use clip-path if you set the same background image on the content box. Caveat: background-attachment needs to be fixed. And if you use flex for all the boxes, just setting position: absolute on the content would be enough to center it on top.
html, body, .bg {
height: 100%;
width: 100%;
}
.bg, .blur-box, .content-box {
display: flex;
align-items: center;
justify-content: center;
}
.bg, .content-box {
background: url(https://picsum.photos/seed/1/1920/1080/) no-repeat fixed 0 0 / cover;
}
.blur-box {
position: relative;
width: 70vh;
height: 70vh;
backdrop-filter: blur(5px);
}
.content-box {
position: absolute;
width: 50vh;
height: 50vh;
color: white;
border: 1px solid white;
}
<div class="bg">
<div class="blur-box">
</div>
<div class="content-box">
TEXT
</div>
</div>

How to make an element on top of a div in the same background color?

I'm trying to create a button for my website that has the same color as the background, even when its size changes.
Basically, the button is on top of a div with white background, that is on top of the body which has gradient background-color.
When I press on the button, its size (scale) changes, and I want it to seem like a cutout/window in the div, that will display the background color.
What I tried to do is to make it gradient, but when it resizes - the gradient background of the button resizes as well. Also that solution is inelegant...
My cite's code:
function chg()
{
document.getElementById("main_div").style.width = "80%";
document.getElementById("catch_div").style.right = "7%";
document.getElementById("enter_div").style.left ="4%";
}
html,body, #main_div{
height: 100%;
overflow: hidden
}
body {
background-color: #1862A1;
background-image: linear-gradient(90deg, #1862A1, #8529B1);
padding-bottom: 0;
padding-top: 0;
margin: 0;
}
#main_div{
height: 100%;
width: 100%;
transition:all 0.3s ease-in-out;
background-color: white;
}
.logo{
width: 48.125vw;
height: 22.3046875vw;
}
#catch_div{
right: 40%;
position: relative;
transition:all 0.3s ease-in-out;
margin-top: -3vw;
}
#enter{
display: block;
width: 6vw;
height: 6vw;
box-shadow: 0 0 0 1px #fff;
text-align: center;
line-height: 136px;
border-radius: 100%;
text-decoration: none;
transition: all 250ms;
outline: 0;
background-color: transparent;
border: 1px solid red;
}
#enter:active{
transform: scale(.90);
}
#enter:active #VButton {
-webkit-transform: rotate(180deg);
-moz-transform: rotate(180deg);
-o-transform: rotate(180deg);
transform: rotate(180deg);
-webkit-transition-duration: 0.25s;
-moz-transition-duration: 0.25s;
-o-transition-duration: 0.25s;
transition-duration: 0.25s;
}
#enter_div{
left: 40%;
position: relative;
transition:all 0.3s ease-in-out;
margin-top: 3vw;
}
.catchphrase{
font-family: Niconne;
font-size: 3.5vw;
font-weight: 400;
color: #1761A0;
}
#cspan{
background: -webkit-linear-gradient(to right, #1761A0 0%, #6B38B0 110%);
background: -moz-linear-gradient(to right, #1761A0 0%, #6B38B0 110%);
background: linear-gradient(to right, #1761A0 0%, #6B38B0 110%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background: linear-gradient(90deg, #1862A1, #8529B1) center fixed;
background-size: cover;
-webkit-text-fill-color: transparent;
-webkit-background-clip: text;
}
#VButton{
width: 5.33vw;
height: 5.33vw;
margin-left: 0vw;
margin-top:0.31vw;
position:relative;
}
<body onload="chg()">
<form id="form1" runat="server">
<center>
<div style="min-height: 100vh;" id="main_div">
<asp:Image runat="server" ImageUrl='~/BETTER_logo.png' ID="logo" CssClass="logo"></asp:Image>
<div id="catch_div"><asp:Label ID="Label1" runat="server" Text="Label" CssClass="catchphrase">Feel <span id="cspan">the rythem</span></asp:Label></div>
<div id="enter_div">
<button type="button" id="enter">
<center><img src="VButton.png" id="VButton"></center> <!-- problem -->
</button>
</div>
</div>
</center>
</form>
</body>
Is something like that even possible? Anyone has a direction that he can point me into?
Tried looking online for something close, but with no luck, I would appreciate any help
EDIT: I would love for the cut out to be able to move, so that I'll be able to create animations in my site in the future with my JS code.
You could create a 'hole' in the white div and place the button (with a transparent background) over it and scale them when clicked. That way the background image of the body will always show through and you don't have to worry about the button's background.
The way to create a hole is to give the white div a radial gradient, positioned where you want the button and with the first part transparent, and then white to the edge.
Here is a small example, the parameters for width etc are in CSS variables to make it easy to play around. Obviously put your own backgrounds for the body in and your own dimensions.
UPDATE the question was expanded to ask how to move the hole. The method here is to move the whitediv - we make it twice the dimensions of those that are actually seen on the screen so that as it moves the viewable part remains white.
Note any other elements that are on top of the white need to be taken out of whitediv and displayed over it so they don't move as the hole moves.
The demo simply expands/contracts the hole if the hole is clicked on and 'moves' the hole if the white part is clicked on [this last bit just for a demo]. Click the white part to see the hole 'fly in'.
const button = document.querySelector('.enter');
const whitediv = document.querySelector('.whitediv');
let n = 0; //just for a test to move the hole (whitediv) around
button.addEventListener('click', function (ev) {
ev.stopPropagation();
whitediv.style.transform = whitediv.style.transform.includes('scale(1)') ? whitediv.style.transform.replace('scale(1)', 'scale(var(--s))') : whitediv.style.transform.replace('scale(var(--s))', 'scale(1)');
});
//just for a demo we move the hole around a little bit if the whitediv is clicked
whitediv.addEventListener('click', function (ev) {
n = (n+1)%3;
whitediv.style.transform = 'translateX(-' + (10*n) +'%) translateY(-' + (10*n) +'%) scale(1)';
});
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
background-image: linear-gradient(red,orange,yellow,green,blue,indigo,violet);
width: 100vw;
height: 100vh;
}
.container {
--x: 30%; /* distance from the left of the white div to center of the hole */
--y: 40%; /* distance from the top to the center of the hole */
--d: 10vmin; /* the diameter of the hole to start with */
--s: 2; /* the scaling factor - factor by which the hole will expand on clicking */
--w: 40vw; /* width of the white div */
--h: 40vh; /* height of the white div */
--top: 10%; /* position of the white div */
--left: 20%;
position: relative;
top: var(--top);
left: var(--left);
width: var(--w);
height: var(--h);
overflow: hidden;
border: 4px white;
}
.whitediv {
position: relative;
width: 100%;
width: 200%;
height: 100%;
height: 200%;
background-image: radial-gradient(circle at var(--x) var(--y), transparent 0%, transparent calc(var(--d) / 2), white calc(var(--d) /2), white 100%);
transition: all 2s;
transform: scale(1) translateX(-50%) translateY(-50%);
transform-origin: var(--x) var(--y);
overflow: hidden;
}
.enter {
background-color: transparent;
height: var(--d);
width: var(--d);
position: relative;
top: var(--y);
left: var(--x);
transform: translateX(-50%) translateY(-50%) scale(1);
border-radius: 50%;
border-style: none;
}
<div class="container">
<div class="whitediv">
<div class="enter">
</div>
</div>
</div>
Here are two ways to do what you wanted to do:
You could create a div with a button. You give the div a background colour. In this case it is blue. Then you give the button the background colour transparent to make the button transparent and the background colour is taken from the div. It is a bit difficult to explain. Therefore here is an example:
div {
background: blue;
width: 300px;
height: 300px;
}
button {
background: transparent;
color: white; /* The button has a white colour to make it easier to see. /*
}
<h2>The background colour of the button was taken from the div</h1>
<div>
<button>Hello World!</button>
</div>
Then there is a second possibility. You can address the div and the button at once. To do this, you have to separate the properties with a ,.
Here is an example:
div {
height: 50px;
width: 100px;
}
/* giving both a background color */
div, button {
background: red;
}
<div>
<button>Hello World</button>
</div>
<h2>Even if the button is not in the div, it has the same background colour.</h2>
<button>Second Button</button>
<br>
<br>
<button>Third Button</button>

Is it possible to make a hole in an img element using html/javascript/css?

I am developing a website from which the background partly needs to be transparant because a video behind it needs to come through. The background is an image. Also, I need to make sure that the website runs on Opera version 11.
Is there a way to cute a hole in an image element, taking into account that the website needs to run in an Opera 11 browser?
<img src='http://ip/cutaholeinme.png'>
So that in the end, the following image with a hole is displayed; (the white rectangle should be transparent)
A mask can easily do this
img {
-webkit-mask:
linear-gradient(#fff,#fff) top / 100% 50px, /* show 50px from the top */
linear-gradient(#fff,#fff) bottom/ 100% 70px, /* show 70px from the bottom */
linear-gradient(#fff,#fff) left / 20% 100%, /* show 20% from the left */
linear-gradient(#fff,#fff) right / 40% 100%; /* show 40% from the right */
-webkit-mask-repeat:no-repeat;
mask:
linear-gradient(#fff,#fff) top / 100% 50px,
linear-gradient(#fff,#fff) bottom/ 100% 70px,
linear-gradient(#fff,#fff) left / 20px 100%,
linear-gradient(#fff,#fff) right / 40px 100%;
mask-repeat:no-repeat;
}
body {
background:linear-gradient(to right,blue,red);
}
<img src="https://picsum.photos/id/1006/500/400" >
For better support, you can consider an SVG mask: How to apply background to specific elements only?
You can also consider a trick with multiple elements like below:
.box {
width: 500px;
height: 400px;
position: relative;
background-size: 0 0;
}
.box div {
background: inherit;
height: 100%;
}
.box:before,
.box:after,
.box div:before,
.box div:after {
content: "";
position: absolute;
background-image: inherit;
background-size: 500px 400px;
}
.box:before,
.box:after {
left: 0;
right: 0;
}
.box:before {
top: 0;
background-position:top;
height: 20%;
}
.box:after {
bottom: 0;
background-position:bottom;
height: 30%;
}
.box div:before,
.box div:after {
top: 0;
bottom: 0;
}
.box div:before {
left: 0;
background-position:left;
width: 40px;
}
.box div:after {
right: 0;
background-position:right;
width: 80px;
}
body {
background: linear-gradient(to right, blue, red);
}
<div class="box" style="background-image:url(https://picsum.photos/id/1006/500/400)">
<div></div>
</div>

Is a see-through child div possible?

The image is the grandparent div, the black translucent overlay is the parent div, and the cropped section is the child div. User will see the grandparent image and the parent overlay, then he can crop through it using the child cropper div. I tried and failed with opacity and rgba background.
These crazy approaches do seem to work for me -
Set the grandparent image in the background of the child div as well and then change the x/y of the background-position.
Combine child and parent into one single div, and use rgba border as the overlay (my friend's suggestion).
Found this on stackoverflow, which uses box-shadow instead of borders and seems like a similar approach to #2.
My minor gripe with #2 and #3 is that I'll need to add another div for the dashed borders so the user clearly knows what he's cropping. But my bigger gripe with all of them is that none of these looks like the right approach.
Is there a proper / better / 2018-ish / "its so obvious, you idiot" way to do this?
Update: Here's the basic markup (I am okay with a different markup too if that helps in solving this)
#grandparentImage {
background: url(https://9to5mac.com/wp-content/uploads/sites/6/2018/07/Desert-2.jpg) no-repeat;
background-size: cover;
position: relative;
height: 500px;
}
#parentOverlay {
background: rgba(0,0,0,0.5);
height: 100%;
position: relative;
}
#childCropper {
border: 1px dashed #ccc;
left: 50px;
height: 100px;
width: 100px;
position: absolute;
top: 50px;
}
<div id="grandparentImage">
<div id="parentOverlay">
<div id="childCropper"></div>
</div>
</div>
Edit: It is not a duplicate of the marked question, since that question deals with how to grab the cropped image, this one deals with how to show the user what he's cropping. More about UI than data.
You can set box-shadow with 100vmax spread radius on the #childCropper. In this way it will always cover the screen:
#grandparentImage {
background: url(https://9to5mac.com/wp-content/uploads/sites/6/2018/07/Desert-2.jpg) no-repeat;
background-size: cover;
position: relative;
height: 500px;
}
#childCropper {
position: absolute;
top: 50px;
left: 50px;
height: 200px;
width: 200px;
border: 1px dashed #ccc;
box-shadow: 0 0 0 100vmax rgba(0,0,0,0.5);
}
body {
margin: 0;
}
<div id="grandparentImage">
<div id="childCropper"></div>
</div>
This seems like a perfect job for pseudo-elements. So this solution is an upgrade of #2 suggestion in the question, but instead of using the element itself, it uses :after:
#grandparentImage {
background: url(https://upload.wikimedia.org/wikipedia/commons/thumb/e/e5/%D0%94%D0%B7%D0%B5%D0%BC%D0%B1%D1%80%D0%BE%D0%BD%D1%8F._%D0%9F%D0%B5%D1%80%D0%B2%D1%8B%D0%B5_%D0%BB%D1%83%D1%87%D0%B8_%D1%81%D0%BE%D0%BB%D0%BD%D1%86%D0%B0.jpg/800px-%D0%94%D0%B7%D0%B5%D0%BC%D0%B1%D1%80%D0%BE%D0%BD%D1%8F._%D0%9F%D0%B5%D1%80%D0%B2%D1%8B%D0%B5_%D0%BB%D1%83%D1%87%D0%B8_%D1%81%D0%BE%D0%BB%D0%BD%D1%86%D0%B0.jpg) no-repeat;
background-size: cover;
position: relative;
height: 500px;
overflow: hidden;
z-index: 1;
}
#childCropper {
border: 2px dashed #ccc;
position: absolute;
top: 50px;
left: 50px;
height: 200px;
width: 200px;
}
#childCropper:after {
content: "";
width: 100%;
height: 100%;
border: 1000px solid rgba(0, 0, 0, 0.5);
position: absolute;
top: -1000px;
left: -1000px;
z-index: -1;
}
<div id="grandparentImage">
<div id="childCropper"></div>
</div>
Note: There will be no need for the #parentOverlay element anymore. Also this solution requires the grand-parent element to have an overflow: hidden property and a z-index (why?).
I'm guessing this is what you're looking for:
overlay-mask {
background-color: rgba(0,0,0,.65);
clip-path: polygon(0% 0%, 75% 0%, 75% 25%, 25% 25%, 25% 75%, 75% 75%, 75% 0%, 100% 0%, 100% 100%, 0 100%);
z-index: 1;
pointer-events: none;
/* rest is optional, you could use
* `position:absolute` to place it in a parent with `relative`
*/
position: fixed;
top: 0; bottom: 0; left: 0; right: 0;
}
body {
margin: 0;
background: url("https://loremflickr.com/800/600") no-repeat center center /cover;
min-height: 100vh;
}
<overlay-mask></overlay-mask>
It's a simple shape following the polygon of the dark area. Points position can be expressed in percentage, using calc() or even providing a custom <svg> by id (and use an external tool, like Adobe Illustrator to generate it.
Current browser coverage: 87.99%.
You can have any content under the mask. And, instead of using position:fixed, you could use position:absolute and place it in the desired container with position:relative, to apply to that container.
Another method is to use <svg>s <path>. Animating them is pretty straight forward using either smil animations or plain CSS keyframes.
Example:
#overlay-mask {
z-index: 1;
pointer-events: none;
/* rest is optional, you could use
* `position:absolute` to place it in a parent with `relative`
*/
position: fixed;
top: 0; bottom: 0; left: 0; right: 0;
color: rgba(0,0,0,.65);
width: calc(100% + 4px);
height: calc(100% + 4px);
left: -2px;
top: -2px;
}
body {
margin: 0;
background: url("https://loremflickr.com/800/600") no-repeat center center /cover;
min-height: 200vh;
}
h2 {color: white;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg id="overlay-mask" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
preserveAspectRatio="none"
viewBox="0 0 600 600" width="600" height="600">
<defs>
<path d="M0 600L0 0L600 0L600 600L0 600ZM100 200L200 200L200 100L100 100L100 200Z" id="cutPath">
<animate attributeType="XML" attributeName="d"
values="M0 600L0 0L600 0L600 600L0 600ZM100 200L200 200L200 100L100 100L100 200Z; M0 600L0 0L600 0L600 600L0 600ZM200 300L300 300L300 200L200 200L200 200Z;M0 600L0 0L600 0L600 600L0 600ZM100 300L300 300L300 100L100 100L100 200Z;M0 600L0 0L600 0L600 600L0 600ZM100 200L200 200L200 100L100 100L100 100Z"
keyTimes="0; 0.33; 0.66; 1"
dur="3s" repeatCount="indefinite"
/>
</path>
</defs>
<use xlink:href="#cutPath" opacity="1" fill="currentColor" fill-opacity="1"></use>
<use xlink:href="#cutPath" opacity="1" fill="none" stroke="white" stroke-width="2"
stroke-dasharray="1,1"
></use>
</svg>
<h2>Scroll down...</h2>
Overlaying divs (Proof of Concept)
.parent,
.child {
background-image: url(https://scontent-lht6-1.cdninstagram.com/vp/0f18c710d8dc3ebd48819b3f9f44b5cc/5C28EE7E/t51.2885-15/e35/29094825_1798384780455300_8914767740305145856_n.jpg?se=7&ig_cache_key=MTc0MDQ5MzIwMjE5OTYyODM5MQ%3D%3D.2);
background-size: contain;
}
.parent {
height: 1072px;
width: 1072px;
opacity: 0.3
}
.child {
position: absolute;
top: 150px;
left: 20px;
height: 200px;
width:500px;
background-position: -20px -150px;
background-size: 1072px 1072px
}
<div class="parent"></div>
<div class="child"></div>
Here is another approach that uses only one element where you can rely on gradient and multiple background to create the cropped overlay and also the dotted border:
#grandparentImage {
--g:linear-gradient(rgba(0,0,0,0.5),rgba(0,0,0,0.5));
--t:repeating-linear-gradient(to right ,#ccc 0,#ccc 2px,transparent 2px, transparent 4px);
--b:repeating-linear-gradient(to bottom,#ccc 0,#ccc 2px,transparent 2px, transparent 4px);
background-image:
/*the border*/
var(--t),var(--t),var(--b),var(--b),
/*the overlay*/
var(--g),var(--g),var(--g),var(--g),
/*the image*/
url(https://picsum.photos/1000/800?image=1069);
background-size:
/*the border*/
40% 2px,40% 2px,2px 40%,2px 40%,
/*the overlay*/
100% 30%,100% 30%,20% 40%, 40% 40%,
/*the image*/
cover;
background-position:
/*the border*/
33.33% 30%,left 33.33% bottom 30%,20% 50%,60% 50%,
/*the overlay*/
top,bottom,left center,right center,
/*the image*/
center;
background-repeat:no-repeat;
position: relative;
height: 100vh;
}
body {
margin:0;
}
<div id="grandparentImage">
</div>
The overlay will be formed by 4 gradients as a rectangular shapes and each border will be a repeating gradient to alternate white/transparent.
The hard part is to understand the different values and how the caclulation of background-size/background-position is done. Here is a good reading for this: background-position not working in percentage for linear-gradient
We can also and the dots of your screenshot:
#grandparentImage {
--g:linear-gradient(rgba(0,0,0,0.5),rgba(0,0,0,0.5));
--t:repeating-linear-gradient(to right ,#ccc 0,#ccc 2px,transparent 2px, transparent 4px);
--b:repeating-linear-gradient(to bottom,#ccc 0,#ccc 2px,transparent 2px, transparent 4px);
--d:radial-gradient(#ccc 60%,transparent 62%);
background-image:
/*the dots*/
var(--d),var(--d),var(--d),var(--d),var(--d),var(--d),var(--d),var(--d),
/*the border*/
var(--t),var(--t),var(--b),var(--b),
/*the overlay*/
var(--g),var(--g),var(--g),var(--g),
/*the image*/
url(https://picsum.photos/1000/800?image=1069);
background-size:
/*the dots*/
10px 10px,10px 10px,10px 10px,10px 10px,10px 10px,10px 10px,10px 10px,10px 10px,
/*the border*/
40% 2px,40% 2px,2px 40%,2px 40%,
/*the overlay*/
100% 30%,100% 30%,20% 40%, 40% 40%,
/*the image*/
cover;
background-position:
/*the dots*/
20% 30%,20% 70%,20% 50%,60% 30%,60% 50%,60% 70%,40% 30%,40% 70%,
/*the border*/
33.33% 30%,left 33.33% bottom 30%,20% 50%,60% 50%,
/*the overlay*/
top,bottom,left center,right center,
/*the image*/
center;
background-repeat:no-repeat;
position: relative;
height: 100vh;
}
body {
margin:0;
}
<div id="grandparentImage">
</div>

How do I cutout shapes from a JS banner?

I am currently working on a PSD (pictured below) for a client and am looking for guidance on how to cut specific shapes from a JS slider. My initial thought process is to overlay css shapes at the bottom of the banner to get the desired effect, as shown in the picture.
I was wondering if there is an alternative to that method. I've looked around on the internet but can't find much info on what I'm trying to accomplish.
All advice welcomed. Thank you in advance.
You can also use viewport width to achieve this objective. I hope it is helpful to you.
.box {
width: 100%;
height: 300px;
position:relative;
background: #000;
}
.box:before
{
border-top:80px solid transparent;
border-left: 50vw solid #fff;
content: '';
position: absolute;
bottom: 0;
left: 0;
}
.box:after
{
border-top:80px solid transparent;
border-right: 50vw solid #fff;
content: '';
position: absolute;
bottom: 0;
right: 0;
}
<div class="box"></div>
You could use this tool for creating CSS clip-paths.
One example would be:
.container {
background-color: orangered;
width: 100%;
height: 200px;
-webkit-clip-path: polygon(100% 0%, 100% 75%, 50% 100%, 0 75%, 0 0);
clip-path: polygon(100% 0%, 100% 75%, 50% 100%, 0 75%, 0 0);
}
<div class="container"></div>

Categories