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

Displaying a hand cursor on a bar chart when hovered over in c3.js

When using pie charts in c3js, a hand cursor (pointer) is displayed by default when hovering over a pie slice. I am looking to achieve the same behavior for each bar in a bar chart. How can this be done? I attempted the CSS below, but it resulted in the h ...

Using Vue/Nuxt.js to compute the cumulative sum of hierarchically structured JSON data

When using Nuxt async data, I am retrieving a JSON object that includes a nested array in the following structure: "topic_list": { "topics": [ { "id": 9148, "title": "A", "views": 12 }, { "id": 3228, ...

The functionality to deselect multiple options in a select box is not functioning properly

There seems to be an issue with removing the selected attribute from the selected values in a jQuery multiselect box. The console is not showing any errors. You can view a working example here The problem lies in this code snippet: $("#mltyslct option ...

Closing a Vue modal with a button

Utilizing the bootstrap-vue framework for my modal, I encountered an issue. Upon clicking the button labeled OPEN MODAL, the modal opens with footer buttons OK and CANCEL, which work as expected to close the modal as per bootstrap-vue's default behavi ...

What is the best way to transfer static assets from an npm package to a nuxt project?

Has anyone successfully sent assets from an npm package to a nuxt application before? I have a vue component within an npm package with the following structure: -src/ -assets/ -noun-filter.svg In this npm package, the vector image is included in the v ...

rearranging nodes from multiple arrays into a single array and then repositioning them within the parent array using angularjs

[![enter image description here][1]][1]I am working with AngularJS and I have multiple arrays named list1, list2, and list3. Each array is used in a different list. Within my application, there are two buttons and two divs - the left div displays elements ...

What could be causing the PAGE CSS to malfunction?

I am looking to export HTML text as a word document with A4 size and portrait orientation. My JavaScript currently allows me to export the text, but it appears like a webpage format rather than in A4 or portrait mode. I have tried adding @page CSS styling ...

Challenges related to maintaining a webpage's content using AJAX

I have a form that I want to use to send and insert the values into my database. After the values are inserted, I would like to clear the input fields of the form and display a success message. Here's an example of how I would like it to look: Clear ...

Utilizing Highcharts-vue for Interactive Stacked Column Charts with Drilldown Feature

I'm currently attempting to recreate a chart similar to the one shown in this example using Vue.js. Admittedly, I am in the process of learning Vue.js, so I find it beneficial to replicate existing projects as a way to build confidence quickly. One ...

The HTML code does not seem to be acknowledging the CakePHP link

When using Cakephp to generate a link with Html->link, the code looks like this: echo $this->Html->link('Download',array( 'plugin'=> 'galleries', 'controller'=> 'galleries', 'a ...

Flexbox - managing wrapping on legacy devices

Utilizing flexbox, I have successfully designed a 2 column layout with a div at the top spanning both columns for a menu format. While this works flawlessly in Chrome and iOS7, it appears to be ineffective in outdated versions of Safari. In this fiddle, yo ...

Improving Performance of a Large Unordered List using JavaScript

My website currently features a search box that retrieves images and displays them in a list format. Each image has an associated click event that triggers an overlay on the parent li element when clicked. However, with search results exceeding 300 images ...

Failed commitments in JavaScript without a catch block (unhandled rejection)

When working on my project in VueJs JavaScript, I want to be able to see console messages if any of my Promises are not fulfilled and do not have a catch block. I attempted using the following code: Promise.reject("error!"); window.addEventListener(&apos ...

Navigating through the content of slots within recurring slots in a subcomponent in Vue.js

I am encountering an issue with a child component, where each row in an object is rendered inside a div with a specific slot. I need to pass data from the parent for each of these elements. I've been attempting to iterate through every element of the ...

Trouble with CSS in a WordPress theme utilizing a two-column layout

After setting up my wordpress blog (http://raptor.hk), I encountered an issue with aligning the right sidebar correctly. It seems like I have overlooked something in the CSS code. The div responsible for the sidebar has been assigned the name "rightbar". I ...

Implementing JavaScript Code in TypeScript

Every JavaScript code should also be valid in TypeScript, but when attempting to run the following code snippet below, an error is triggered. Could someone convert this JavaScript code into TypeScript? Error: 20:9 - TS2531 Error: Object is possibly 'z ...

The HTML attribute "hasbox" specifies the presence of a box within the element

I am currently working on resolving some rendering issues specifically in IE9 and have encountered a tag attribute that I am not familiar with - hasbox. Upon further investigation, it seems like IE is injecting this attribute at runtime as it does not app ...

Creating an HTML document with unique characters

I am currently facing an issue with writing special characters in HTML. My program is designed to edit an HTML file and allow users to replace content using a text box. However, I am struggling to add characters like "ç", "á", "ö", etc. These character ...

Tips for creating a Vue component that triggers the select dropdown to open when the entire div or wrapper is clicked

I have a custom-designed select dropdown with unique symbols for the select arrow. To achieve this look, I've hidden the default select arrow/triangle and placed our symbol on top as an image file. <div class="select-wrapper"> < ...

Modifying the Placeholder Color in a Material UI Autocomplete: Tips and Tricks

In my team, we are working on two projects that both utilize an internal library with a header containing a search box. In one project, the placeholder text "Search" displays normally. https://i.stack.imgur.com/lhL5V.png However, in the second project wh ...