-2

I'm looking to simply cutout or mask a div using another div.

In this example: JSFiddle I aim to cutout 'mainDiv' with the white 'maskDiv', so you can see the background where the white square is.

.background{
  width: 100%;
  height: 100%;
  background-image: url("https://www.1800flowers.com/blog/wp-content/uploads/2021/05/Birthday-Flowers-Colors.jpg");
}

.mainDiv{
  width:150px;
  height:150px;
  background: red;
}

.maskDiv{
  width:50px;
  height:50px;
  border-radius: 10px;
  background: white;
  
  position: relative;
  left: 50%;
  top: 10%;
}
<div class="background">
  <div class="mainDiv" />
  <div class="maskDiv" />
</div>
H3AR7B3A7
  • 4,366
  • 2
  • 14
  • 37
  • @FrancescoRusso Please provide more details, with an example div. Also more detail of what you mean by cutout or mask. Familiar language like "any help will be appreciate" will be edited out, as it isn't related to the question. – James Risner Feb 23 '23 at 21:05
  • 1
    Sure, https://jsfiddle.net/06f38kds/ . My aim is to cutout the white div. –  Feb 23 '23 at 21:15
  • Thanks for the jsfiddle. So can you describe why you can't use what is in the fiddle? – James Risner Feb 24 '23 at 00:32
  • For a simple start have you tried clip-path? To cut a 'hole' that is rectangular shape is relatively simple, you just have to be careful that you define a full path that goes round the outside of the whole underneath element as well as 'comes in' and 'goes out' of the inside by the same route. For more complex shapes take a look at mask. – A Haworth Feb 24 '23 at 15:44

1 Answers1

0

HTML Limits

You can't cut out of divs like you do in Photoshop. There is hierarchy to your html tags that you can't over-rule.

Here are some creative ways around it though.

Re-using image or content from the div you want to mask

You can re-use the same image and position it right:

.background{
  width: 100%;
  height: 100%;
  background-image: url("https://www.1800flowers.com/blog/wp-content/uploads/2021/05/Birthday-Flowers-Colors.jpg");
}

.mainDiv{
  width:150px;
  height:150px;
  background: red;
}

.maskDiv{
  width:50px;
  height:50px;
  border-radius: 10px;
  background-image: url("https://www.1800flowers.com/blog/wp-content/uploads/2021/05/Birthday-Flowers-Colors.jpg");
  background-position: -50px -10px;
  
  position: relative;
  left: 50%;
  top: 10%;
}
<div class="background">
  <div class="mainDiv" />
  <div class="maskDiv" />
</div>

You might however want to use other measurements than %'s if you want to get it to match perfectly.

Being creative with (multiple) divs

.background {
  width: 100%;
  height: 100%;
  background-image: url("https://www.1800flowers.com/blog/wp-content/uploads/2021/05/Birthday-Flowers-Colors.jpg");
}

.mainDiv {
  width: 150px;
  height: 150px;
  display: grid;
  grid-template-columns: 2fr 1fr 1fr;
  grid-template-rows: .5fr .5fr 1fr;
  gap: 0px 0px;
}

.mainDiv>div {
  background: red;
}

.mainDiv>div:nth-child(5) {
  background-color: unset;
}
<div class="background">
  <div class="mainDiv">
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
  </div>
  <div class="maskDiv" />
</div>

Note that you can use clip-path here on the opposite sides of 2 divs, so you can use 2 instead of 9, and make prettier things than just a square. Here's a rather simple example, but you can expand upon this to make pretty crazy things when you get the hang of it.

.background {
  width: 100%;
  height: 100%;
  background-image: url("https://www.1800flowers.com/blog/wp-content/uploads/2021/05/Birthday-Flowers-Colors.jpg");
  display: flex;
  flex-direction: row;
}

.leftDiv {
  width: 75px;
  height: 150px;
  background-color: red;
  clip-path: polygon(0 0, 100% 0, 100% 25%, 50% 25%, 50% 75%, 100% 75%, 100% 100%, 0 100%);
}

.rightDiv {
  width: 75px;
  height: 150px;
  background-color: blue;
  clip-path: polygon(100% 0, 0 0, 0 25%, 50% 25%, 50% 75%, 0 75%, 0 100%, 100% 100%);
}
<div class="background">
  <div class="leftDiv"></div>
  <div class="rightDiv"></div>
</div>

Or even with just one, if you like headaches:

.background {
  width: 100%;
  height: 100%;
  background-image: url("https://www.1800flowers.com/blog/wp-content/uploads/2021/05/Birthday-Flowers-Colors.jpg");
  display: flex;
  flex-direction: row;
}

.outerSquare {
  width: 150px;
  height: 150px;
  background-color: red;
  clip-path:  polygon(
    0 0,       /* top left corner */
    0 100%,    /* bottom left corner */
    25% 100%,  /* inner x-offset */
    25% 25%,   /* inner top left corner */
    75% 25%,   /* inner top right corner */
    75% 75%,   /* inner bottom right corner */
    25% 75%,   /* inner bottom left corner */
    25% 100%,  /* inner x-offset return */
    100% 100%, /* bottom right corner */
    100% 0     /* top right corner */ 
  );
}
<div class="background">
  <div class="outerSquare"></div>
</div>

Use a gif / svg resource with transparency

you can just create an image in Photoshop or Gimp that has an alpha channel, making it transparant where you need it to be, and use that as your mask.

Or you can create an svg:

.background {
  width: 100%;
  height: 100%;
  background-image: url("https://www.1800flowers.com/blog/wp-content/uploads/2021/05/Birthday-Flowers-Colors.jpg");
}
<div class="background">
  <svg viewbox="0 0 100 50">
    <defs>
      <mask id="mask">
        <rect x="0" y="0" width="50" height="50" fill="#fff"/>
        <rect x="30" y="10" width="15" height="15" rx="3" />
      </mask>
    </defs>
    <rect width="50" height="50" mask="url(#mask)" fill="#f00" fill-opacity="1.0" />
  </svg>
</div>

In this case you are masking a rectangle in the svg, so again you are not actually masking a div.

H3AR7B3A7
  • 4,366
  • 2
  • 14
  • 37
  • Appreciate the response, but in my project I need the cutout to show various divs and text. It's not as simple as revealing a background. This is just a minimal reproducible example. –  Feb 24 '23 at 03:32
  • 1
    @FrancescoRusso I added some more options for you, but I'm afraid you'll need to be creative in some way, because what you are asking is just not supported in html. – H3AR7B3A7 Feb 24 '23 at 15:36