[Vuejs]-How to make part of a div transparent to show what's underneath?

1👍

You can use the ::after element to provide the circle, just use CSS variables to provide a constant image.

function applyZoom() {
  const zoomValue = document.getElementById('sizeinput').value;
  const zoom = '--zoom:' + zoomValue + ";"
  document.getElementById('myavatar').setAttribute('style', zoom);
}
.mydiv {
  --image: url('https://picsum.photos/id/46/300/300');
  --size: 400px;
  display:grid;
  place-items:center;
  width:400px;
  border-radius: 2rem;
  background-image:  linear-gradient(rgba(56, 76, 111, 0.5), rgba(56, 76, 111, 0.5)), var(--image);
   
}

.mydiv, .mydiv::after {
  aspect-ratio:1;
  background-position: center center;
  background-repeat: no-repeat;
  background-size: calc(var(--zoom) * var(--size)) calc(var(--zoom) * var(--size));
}

.mydiv::after {
  display:block;
  content:"";
  width:200px;
  border:2px solid white;
  border-radius:100vh;
  background-image: var(--image);
}
<div class='mydiv' id='myavatar' style='--zoom: 1;'>
</div>
<br>
<input id='sizeinput'><button onclick='applyZoom()'>Zoom</button>

Edited to add
In the comment, there’s a need to zoom the image. Just using the ::after pseudo elemnt, the overlay shading sizes with the image. This isn’t a problem for zooms greater than 1 but if it’s less than 1, it breaks. This can be solved by using the ‘before’ element and z-index as follows:

function applyZoom() {
  const circleWidth = 200;
  const zoomValue = document.getElementById('sizeinput').value;
  document.getElementById('zoomText').textContent = zoomValue;
  
  const zoom = '--zoom:' + zoomValue + ";"
  const element = document.getElementById('myavatar');
  
  const containerSize = parseInt(window.getComputedStyle(element).getPropertyValue("--size"));
  const resizedImageSize = containerSize * zoomValue;
  
  if(resizedImageSize >= circleWidth) {
    element.setAttribute('style', zoom);
    }
}
.mydiv {
  --image: url('https://picsum.photos/id/46/300/300');
  --size: 400px;
  position:relative;
  overflow: hidden;
  display:grid;
  place-items:center;
  width:400px;
  border-radius: 2rem;
  background-image:  var(--image);
}

.mydiv, .mydiv::after {
  aspect-ratio:1;
  background-position: center center;
  background-repeat: no-repeat;
  background-size: calc(var(--zoom) * var(--size)) calc(var(--zoom) * var(--size));
}

.mydiv::before {
  display:block;
  position: absolute;
  content:"";
  inset: 0;
  width:100%;
  background-color: rgba(56, 76, 111, 0.8);
}

.mydiv::after {
  display:block;
  content:"";
  width:200px;
  border:2px solid white;
  border-radius:100vh;
  background-image: var(--image);
  z-index: 1;
}
<div class='mydiv' id='myavatar' style='--zoom: 1;'>
</div>
<br>
<input type="range" min="0" max="2" value="1" step="0.1" id="sizeinput" oninput='applyZoom()'>
Zoom: <span id='zoomText'></span>
👤Adam

1👍

This snippet makes use of the mask-box-image property

.masking{
  width: 300px;
  height: 300px;
  -webkit-mask-box-image: radial-gradient(circle at 50% 50%, gray 60%, rgba(140, 140, 140, 0.3) 60%);
}
<img src="https://music.columbia.edu/sites/default/files/styles/page_image_square/public/images/stylianos_dimou_profile-alt.jpg?itok=mOF8wxnL" class="masking">

Source

👤Inglan

1👍

What about making it two distinct elements?

* {
  box-sizing: border-box;
}

.background, .foreground {
  background: url("https://picsum.photos/500") 50% 50%/500px 500px;
}

.background {
  width: 500px;
  height: 500px;
  position: relative;
  padding: 50px;
}
.background::after {
  content: "";
  background: rgba(0, 0, 0, 0.5);
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}

.foreground {
  position: relative;
  height: 100%;
  z-index: 1;
  border-radius: 100%;
  border: 2px solid #fff;
}
<div class="background">
  <div class="foreground"></div>
</div>

Leave a comment