What is the best way to create a transparent section within a div to reveal the content below?

My goal is to create a user interface that resembles the design shown in this image https://i.stack.imgur.com/GfiZ8.png

One issue I'm facing is how to make the center of the top div circular and transparent, just like in the reference image.

I considered using canvas for this task but my research only yielded results on how to create circular canvases, not circular and transparent elements as desired.

Answer №1

To create a circle using CSS, you can utilize the ::after pseudo-element and define constant images with CSS variables.

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>

Update: In order to handle image zooming when the zoom value is less than 1, an adjustment is needed by introducing the 'before' element with z-index as shown below:

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>

Answer №2

This code snippet demonstrates the usage 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

Answer №3

Have you considered separating them into two different 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>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

When attempting to parse a JSON feed with jQuery and innerHTML, the data fails to display

Having trouble parsing a JSON feed using jQuery and innerHTML, but for some reason it's not working as expected. No errors are being displayed in the console and the feed itself is functioning properly. Not quite sure why this issue is occurring. < ...

The slider causing conflicts with widgets and content positioned below it in an HTML layout

When implementing a slider with a fade effect, there seems to be an issue with the placement of widgets on the homepage. The problem arises from the margin-top setting as when images change in the slider, the widgets clash with the slider. During the trans ...

Enhancing User Experience with CSS

Is there a way to create a link within a div and change the hover color to indicate it's a link? The challenge is that my div contains both an image and text in separate divs. div { :hover { background-color: light cyan; } Currently, when I hov ...

How can I remove the gaps between Bootstrap panels on a website?

The Issue https://i.stack.imgur.com/I5EFR.png My problem is with the spacing between the panels, highlighted in red. I've attempted to remove them by using the following CSS: .panel { margin-top: 0; margin-bottom: 0; padding-top: 0; ...

Trouble triggering hidden radio button in Angular 9 when clicked

I have implemented radio buttons within a div with the following CSS styles (to enable selection by clicking on the div): .plans-list { display: flex; justify-content: center; margin: 2rem 0; .plan { display: flex; margin: 0 0.5rem; p ...

Having trouble with v-slide-group when there are only a few items present

I am encountering an issue with v-slide-group. Sometimes, I have only 2-3 items and other times, I have 10 items or more. However, when there are fewer items, the arrows do not show up and the slide-items are not centered. <div id="app"> ...

What is the best way to create space between floated elements and a cleared element?

I have a webpage with various floated boxes and a footer positioned at the bottom. The issue arises when trying to create space between the boxes and the footer without using margins. #main { max-width: 700px; margin: 0 auto; } .box { width: 46.6 ...

`Eliminate a few bbcodes in the code snippet`

I am currently experiencing an issue with a bbcode parser that converts to HTML. Whenever I try to parse the code, I encounter problems with tags that are not in my approved set by the parser. For instance: The parser only permits [b], [center], and [i] t ...

Animating a dotted border path in SVG for a progress bar effect

I am attempting to create an animation for a dotted SVG circle that resembles a progress bar, where it fills itself over a duration of 3 seconds. However, I am facing difficulties in achieving this effect with the dotted border. The current code I have doe ...

turn the cube shape into one with smooth, rounded corners

Does anyone know how to create a cube with rounded corners using three.js? I've heard it's not possible with CSS. Any guidance on how to achieve this? Check out this link for an example /* |------------------------------------------| | MelonHTM ...

Customizing v-model in a Vue component

In an effort to simplify certain sections of my HTML code, I have created a small component: <template> <div class="form-group"> <label for="desc">{{label}}</label> <input id="desc" readonly type="text" class="form-con ...

Using JavaScript (AJAX), learn the process of incorporating XML data within HTML files

I'm relatively new to HTML and I'm attempting to create a self-contained HTML page that includes all necessary CSS, data, and JavaScript within the file itself. While I understand that this will result in a rather messy HTML document, it is essen ...

Enhance your browsing experience with Fire-fox add-on that automatically triggers JavaScript after YouTube comments have

I am currently working on creating an add-on for the Firefox browser. I have implemented a page-mod that triggers a script when specific pages (such as Youtube) are loaded, allowing it to communicate data back to the main script. However, I am encountering ...

Designated router perspectives

I am currently working on a Nuxt application that has a layout featuring 3/4 main content and a 1/4 sidebar navigation with expandable tabs based on the current route. My goal is to essentially have two router-views - one on the main page and one in each ...

I'm having trouble accessing the vue.js website. Any ideas on what might be causing this issue?

While testing my SPA site frontend locally, everything was working perfectly. However, after configuring Apache and fixing bugs when trying to access the domain, the site does not show up as expected. Instead, I see a loading element in the center of the p ...

Unifying flex and position:fixed

I'm having difficulties when it comes to displaying a modal dialog with a fixed position within a flex layout. The header and footer of the dialog need to be set in height, while the content section should have overflow with scrollbars. I chose the fl ...

transitioning from a particular class to utilizing props in SCSS and Vue.js

Is there a way to dynamically apply classes based on props without duplicating SCSS code? When I duplicate the code and add the class, it works, but I want to be able to modify specific values by adding the appropriate class. Components :class="[theme === ...

What is preventing my div from reaching 100% height when I implement an HTML5 doctype? Is there a solution to achieving a full height div?

I'm currently working on organizing the layout for a basic gallery webapp, and I've encountered an issue where some of my divs are shrinking in height when using an HTML5 doctype declaration. Despite trying different CSS properties, I can't ...

What is the best way to extract text directly from a span element without including the text of its child nodes?

I am dealing with a piece of HTML that is dynamically generated, and it looks like this: <span> 10/10/2012 <div class="calendar"> lots of text elements here </div> </span> Is there a way to specifically retrieve the tex ...

Forming a header area by utilizing a 960 Grid container

I'm in the process of designing a website utilizing the 960 Grid system. The header consists of three parts: the logo, the navigation, and the login form. I've implemented media queries to center both the logo and the login section when the pag ...