Positioning SVGs within a parent container while maintaining responsiveness

How can I anchor an SVG overlay with a circle in the bottom right corner while expanding the rest of the SVG to fill the remaining area of the container without distorting the circle?

I've been able to position the SVG in the bottom right corner, but I'm struggling to make it fill the rest of the container. Any suggestions on how to achieve this without affecting the circle shape would be appreciated.

View codepen example: https://codepen.io/emilychews/pen/KQmZEd

body {
  width: 100%; 
  height: 100vh;
  padding: 0; margin: 0;
  display: flex;}

#box {
  margin: auto;
  position: relative;
  width: 33%;
  height: 200px;
  background: url(https://lorempixel.com/400/400/) center/cover;
  overflow: hidden;
}

#overlay {
position: absolute;
bottom: 0; 
right: 0;
}
<div id="box">
    <svg id="overlay" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 232.71 170.5"><g id="Layer_2" data-name="Layer 2"><g id="Layer_2-2" data-name="Layer 2-2"><path d="M0,0V170.5H232.71V0ZM187.37,148.19a23,23,0,1,1,23-23h0A23,23,0,0,1,187.37,148.19Z" transform="translate(0 0)" fill="#015668"/></g></g></svg>
</div>

Answer №1

I have come up with an alternative solution for creating a hole using a mask in which you can easily manipulate the position and size of the circle. The key is to ensure that the entire SVG overflows with a large width/height to always cover the div while maintaining the size of the circle:

body {
  width: 100%;
  height: 100vh;
  padding: 0;
  margin: 0;
  display: flex;
}

#box {
  margin: auto;
  position: relative;
  width: 33%;
  height: 200px;
  background: url(https://lorempixel.com/400/400/) center/cover;
  overflow: hidden;
}

#overlay {
  position: absolute;
  bottom: 0;
  right: 0;
  width:1000px;
  height:1000px;
}
<div id="box">
  <svg  id="overlay" viewbox="0 0 400 400" >
  <defs>
    <mask id="hole">
      <rect width="100%" height="100%" fill="white"/>
      <!-- This circle represents the hole -->
      <circle r="20" cx="370" cy="370" fill="black"/>
    </mask>
  </defs>

  <rect x=0 y=0 width=400 height=400 mask="url(#hole)" fill="green" />
    
</svg>
</div>

If you want the circle to adjust its size when the width changes, you can explore this approach:

body {
  width: 100%;
  height: 100vh;
  padding: 0;
  margin: 0;
  display: flex;
}

#box {
  margin: auto;
  position: relative;
  width: 33%;
  height: 200px;
  background: url(https://lorempixel.com/400/400/) center/cover;
  overflow: hidden;
}

#overlay {
  position: absolute;
  bottom: 0;
  right: 0;
  width:100%;
}
<div id="box">
  <svg  id="overlay" viewbox="0 0 400 10000" >
  <defs>
    <mask id="hole">
      <rect width="100%" height="100%" fill="white"/>
      <!-- This circle represents the hole -->
      <circle r="80" cx="300" cy="9900" fill="black"/>
    </mask>
  </defs>

  <rect x=0 y=0 width=400 height=10000 mask="url(#hole)" fill="green" />
    
</svg>
</div>


You can achieve the desired opacity as requested in the previous question with ease:

body {
  width: 100%;
  height: 100vh;
  padding: 0;
  margin: 0;
  display: flex;
}

#box {
  margin: auto;
  position: relative;
  width: 33%;
  height: 200px;
  background: url(https://lorempixel.com/400/400/) center/cover;
  overflow: hidden;
}

#overlay {
  position: absolute;
  bottom: 0;
  right: 0;
  width:100%;
}
<div id="box">
  <svg  id="overlay" viewbox="0 0 400 10000" >
  <defs>
    <mask id="hole">
      <rect width="100%" height="100%" fill="white"/>
      <!-- This circle represents the hole -->
      <circle r="80" cx="300" cy="9900" fill="black"/>
    </mask>
  </defs>

  <rect x=0 y=0 width=400 height=10000 mask="url(#hole)" fill="rgba(0,0,255,0.5)" />
    
</svg>
</div>

Answer №2

Let me guide you through the process step by step to create this effect easily and efficiently.

To begin, we will use a basic square SVG with a viewBox set at 100x100. We can then position the circle that will act as our future hole in the bottom right corner of the viewBox.

body {
  width: 100%;
  height: 100vh;
  padding: 0; margin: 0;
  display: flex;}

#box {
  margin: auto;
  position: relative;
  width: 33%;
  height: 200px;
  background: url(https://lorempixel.com/400/400/) center/cover;
  overflow: hidden;
}
<div id="box">
  <svg width="100%" height="100%" viewBox="0 0 100 100">
    <rect x="0" y="0" width="100" height="100" fill="#015668"/>
    <circle cx="70" cy="70" r="20" fill="black"/><!-- the hole -->
  </svg>
</div>

We will utilize

preserveAspectRatio="xMaxYMax meet"
to specify that the SVG contents should be placed in the bottom right corner.

body {
  width: 100%;
  height: 100vh;
  padding: 0; margin: 0;
  display: flex;}

#box {
  margin: auto;
  position: relative;
  width: 33%;
  height: 200px;
  background: url(https://lorempixel.com/400/400/) center/cover;
  overflow: hidden;
}
<div id="box">
  <svg width="100%" height="100%" viewBox="0 0 100 100" preserveAspectRatio="xMaxYMax meet">
    <rect x="0" y="0" width="100" height="100" fill="#015668"/>
    <circle cx="70" cy="70" r="20" fill="black"/><!-- the hole -->
  </svg>
</div>

Next, extend the rectangle to the left of the viewBox by setting x="-900" and width="1000". This ensures coverage for various monitor sizes.

A similar adjustment is made vertically to account for potential changes in viewport size.

body {
  width: 100%;
  height: 100vh;
  padding: 0; margin: 0;
  display: flex;}

#box {
  margin: auto;
  position: relative;
  width: 33%;
  height: 200px;
  background: url(https://lorempixel.com/400/400/) center/cover;
  overflow: hidden;
}
<div id="box">
  <svg width="100%" height="100%" viewBox="0 0 100 100" preserveAspectRatio="xMaxYMax meet">
    <rect x="-900" y="-900" width="1000" height="1000" fill="#015668"/>
    <circle cx="70" cy="70" r="20" fill="black"/><!-- the hole -->
  </svg>
</div>

Finally, convert this setup into a mask and apply it to a rectangle covering the viewport.

body {
  width: 100%;
  height: 100vh;
  padding: 0; margin: 0;
  display: flex;}

#box {
  margin: auto;
  position: relative;
  width: 33%;
  height: 200px;
  background: url(https://lorempixel.com/400/400/) center/cover;
  overflow: hidden;
}
<div id="box">
  <svg width="100%" height="100%" viewBox="0 0 100 100" preserveAspectRatio="xMaxYMax meet">
    <defs>
      <mask id="mymask">
        <rect x="-900" y="-900" width="1000" height="1000" fill="white" fill-opacity="0.9"/>
        <circle cx="70" cy="70" r="20" fill="black"/><!-- the hole -->
      </mask>
    </defs>
    <rect x="-900" y="-900" width="1000" height="1000" fill="#015668" mask="url(#mymask)"/>
  </svg>
</div>

To test responsiveness, increase the "box" height to 400px and observe its behavior when resizing the browser window.

body {
  width: 100%;
  height: 100vh;
  padding: 0; margin: 0;
  display: flex;}

#box {
  margin: auto;
  position: relative;
  width: 33%;
  height: 400px;
  background: url(https://lorempixel.com/400/400/) center/cover;
  overflow: hidden;
}
<div id="box">
  <svg width="100%" height="100%" viewBox="0 0 100 100" preserveAspectRatio="xMaxYMax meet">
    <defs>
      <mask id="mymask">
        <rect x="-900" y="-900" width="1000" height="1000" fill="white" fill-opacity="0.9"/>
        <circle cx="70" cy="70" r="20" fill="black"/><!-- the hole -->
      </mask>
    </defs>
    <rect x="-900" y="-900" width="1000" height="1000" fill="#015668" mask="url(#mymask)"/>
  </svg>
</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

Enhancing the menu/navigation bar with individual AJAX loaders

I have chosen the Vivant Designs theme for our website, which can be found at What I am looking to achieve is an ajax loader that will appear next to the link or tab when a user clicks on a link within the drilldown menu located on the left side. The cont ...

How to modify an array in an HTML document using BeautifulSoup

Running a Python script, I am trying to access a local HTML file containing a JavaScript array inside a script tag that needs updating. Here is the test code snippet: from bs4 import BeautifulSoup html = ''' <script> var myArray ...

Having difficulty adjusting certain internal styles within Material UI's <Dialog> component

I want to customize the styling of my <Dialog> component by adding rounded corners using a border radius. Here is the inline style I am trying to apply to override the default styles of the <Dialog>: let overrideStyles = { padding: 0, marg ...

Instructions on adjusting the height of a flexbox container to utilize the available space

I am facing a challenge in grasping the interaction between flexbox containers and other elements on a webpage. When I have only a flexbox on my page, everything works smoothly. However, when I introduce other elements, things start acting strangely. It se ...

Incorporating accordion functionality using jQuery within my Model-View-Controller

Struggling to integrate accordion jquery with my MVC view. I want it to show content when @item["name"] is selected, but currently it's not working. Here is the script I'm using: <script> $(function () { $("#parameter_accordion").acco ...

In Internet Explorer 7, there appears to be a white box that covers up the content on our website beyond a

I'm feeling stuck and frustrated trying to solve this issue. I have a Mac and no access to an IE7 machine, so I've been using browserlab (which is slow) to make any changes and see if they help. Unfortunately, I haven't been able to fix the ...

CSS to resolve HTML alignment problems

I am new to HTML and CSS, trying to practice formulating a few things but my efforts are proving futile. Below is the code and images for your reference. I would appreciate your opinion. .container { display: block; width: 200px; height: 120px; } ...

adjust the width of an element based on the size of characters within it

I need to ensure that the width of a div is equivalent to 10 characters If one character is equal to 2px, then I want the width to be 20px, even if the text is only 4 characters long. <div class="row"> <div class="key">City</div> ...

When the browser is refreshed, jQuery will automatically scroll the window down

I created a div that matches the height and width of the window to simulate a "home screen." When scrolling down to view the content, everything works fine. However, after refreshing the browser, it automatically scrolls back to where you were before. I wa ...

Has anyone come across an XSLT that can effectively convert Apple Pages files into high-quality HTML?

When Apple’s word processor/DTP app Pages saves its files, it does so as zipped folders with an XML file containing the content and attachments like images stored as separate files. I am interested in converting this content into HTML format, using < ...

Utilizing Vue's string-based class binding feature?

Can Vue class binding work with strings? For example: <div :class={open: target == 'myString'}></div> var app = new Vue({ target: null }) It works when I don't use quotes <div :class={open: target == myString}></div ...

Is there a way to extract the content within the HTML tags as well as the text enclosed within parentheses?

When working with my HTML content, I came across the following line: <span>(48 עמודים סה"כ )</span> I am seeking a way to extract only the text "48 עמודים סה"כ" and store the number 48 into an integer variable. Although in t ...

Tips for locating direct children of a non-root element using CSS selectors in Selenium

When working with a <table> element, I encountered the need to search for its descendants and direct descendants while avoiding wading through nested tables. The elements I seek lack reasonable IDs, so specific selectors are essential: <html> ...

Instructions for converting a readonly text field into an editable one using JavaScript

I'm trying to make it so that when the button (with id name_button) is clicked, the text field (with id name_text_field) becomes enabled. However, my current code doesn't seem to be working. Here's a snippet of my HTML: <input type="tex ...

Having trouble with the Ajax load function not functioning in your HTML code?

The issue has been resolved. Thank you to everyone who helped! Initially, I was attempting to run a file offline instead of on a web server (XAMPP server). Once I uploaded the file to the web server, it started working properly. I had been trying to load ...

Sliding background in a multi-column accordion

I've hit a roadblock with this project. I'm working on setting up a FAQ section that needs to display its items in two columns on desktop, each with a drop shadow effect using Bootstrap 4. I've experimented with Flexbox and CSS columns with ...

"Optimizing Background Images with IE 8 Stretch Cover in Bootstrap

Page Broken I've searched all over Stack Overflow for a solution to resolve this background image issue. I'm using Bootstrap for the boxes and removed any margins. The problem arises when setting the background as cover; in IE8, it doesn't ...

What causes the iframe to protrude beyond the bottom of the page when set to 100% height?

I am facing an issue with an iframe on my website that is contained within a div. I have specified both to have a height of 100%, and I am using the blueprint framework, hence applying the class span-12 last. Despite these settings, a scroll bar still appe ...

Create a screen divided into two separate sections using horizontal split dividers

Trying to figure out how to set a div in HTML and then have a second div take up the remaining space. It seems like it should be simple, but I'm struggling with it. I'd like to have a div with a fixed height and then have another div take up the ...

What happens when there is no match found while attempting to edit a form with the UI-Bootstrap typeahead directive?

Here is the code that demonstrates how my typeahead input box functions. Users can enter a name, and the relevant information will populate the rest of the form. If no match is found, users should still be able to input the name and related details into th ...