Create a flawless ring encircling a div with adjustable height

Despite my extensive research, I have yet to come across a satisfactory solution for creating a responsive circle that adapts to a div element of variable height.

While it is relatively simple to create a responsive circle using vw units, my challenge lies in achieving the same result when the div has a fluctuating height.

<div style="height:20vw; width:20vw"></div>

A different approach involves the use of CSS properties like in the following code snippet, but I still face difficulty in adjusting it to accommodate variable heights without the use of vh units.

.square {
  position: relative;
  width: 10%;
  background: gray;
  border-radius: 50%;
}

.square:after {
  content: "";
  display: block;
  padding-bottom: 100%;
}

.content {
  position: absolute;
  width: 100%;
  height: 100%;
}
<div class="square">
  <div class="content">
  
  </div>
</div>

My goal is to achieve a design similar to the image below, where the circular shape maintains a consistent padding around the div, ensuring it never overlaps with the corners.

https://i.sstatic.net/yVEhX.png

My experimentation led me to the following CSS code snippet, where I attempted to center the circle within the element and provide it with a minimum height, but I encountered limitations due to the fixed width.

.square {
  position: absolute;
  top: 50%;
  display: inline-block;
  left: 50%;
  transform: translate(-50%, -50%);
  min-height: 100px;
  border-radius: 50%;
  background: url('https://i.imgur.com/2dxaFs9_d.webp?maxwidth=640&shape=thumb&fidelity=medium');
  background-size: 100% 100%;
  padding: 20px;
}

.content {
  width: 300px;
  min-height: 100px;
  background: tomato;
}
<div class="square">
  <div class="content">
    Hello!<br>
    <br><br><br>This has a variable height but fixed width<br><br><br>Hello
  </div>
</div>

Answer №1

You can achieve this effect easily with the <code>clip-path
property, especially when working with solid colors.

Simply resize the element, and the circle will adjust accordingly:

.box {
  width: 200px;
  height: 200px;
  overflow: hidden;
  resize: both;
  background: blue;
  box-shadow: 0 0 0 200vmax red;
  clip-path: circle(71%);
  margin: 100px auto;
}
<div class="box"></div>

For further insights into the specific number 71% used, check the following related question: clip-path:circle() radius seems inaccurately calculated


To incorporate an image, utilizing pseudo-elements is a viable option. Additionally, you can utilize calc() to incorporate an offset:

.box {
  width: 200px;=
  resize: both;
  clip-path: circle(calc(71% + 10px));
  margin: 100px auto;
  position: relative;
  font-size:35px;
  color:#fff;
}
/* the background layer */
.box::before {
  content: "";
  position: absolute;
  z-index: -1;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: blue;
}

/* the image layer */
.box::after {
  content: "";
  position: fixed; /* to ensure the image covers the whole screen */
  z-index: -2;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background: url(https://picsum.photos/id/1015/1000/1000) center/cover no-repeat;
}
<div class="box" contenteditable="true"> Edit this<br>text </div>

Answer №2

After exhausting all my efforts to solve this using only CSS, I encountered a roadblock. The challenge lay in calculating the diameter of a circle based on the size of the content div; essentially, the diagonal length from the top left corner to the bottom right corner of a div with variable height.

It seems that achieving this through the calc() CSS function was beyond my reach.

However, I did find a solution using a bit of jQuery (which can easily be adapted to pure JavaScript if jQuery is not being utilized).

Below is a functioning resizable example (follow the comments in the code for guidance).

Note: If you are using Internet Explorer, the resizable demo content div will not resize correctly.

// function for creating circles around variable-sized divs
function circumscriber() {

  // loop through each variable-sized div on the page
  $(".variable-size").each(function() {

    // retrieve the width and height of the variable-sized div content
    let width = $(this).outerWidth();
    let height = $(this).outerHeight();

    // calculate the diameter for a perfect circle based on content size
    let diameter = Math.sqrt(width ** 2 + height ** 2);

    // add an extra 15 pixels around the circle for edge
    let edge = 15;
    
    // set the current circle size using CSS
    $('.circle', this).css({
      'width': (diameter + (edge * 2)) + 'px'
    })

  });

}

// run the circumscriber function (consider calling this on document ready)
circumscriber();

// update circle sizes responsively when the window is resized
$(window).on('resize', function() {
  circumscriber();
});


// for demo purposes, trigger the circumscriber when resizing content
// this is not necessary for actual implementation
$('.content').on('input', function() {
  this.style.height = "";
  this.style.height = ( this.scrollHeight - 30 ) + "px";
  circumscriber();
}).on('mouseup', function() {
  circumscriber();
});
/* define styles for the variable-sized container circumscribed by a circle */
/* these styles are optional - used to center the variable-sized div in the window for demo purposes */
.variable-size {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

/* define styles for the resizable text area in the demo */
/* these styles are also optional */
.variable-size .content {
  padding: 15px;
  background: #fff;
  resize: both;
  overflow: auto;
  color: #000;
  border: none;
  width: 200px;
  font-weight: bold;
}

.variable-size .content:focus {
  outline: 0;
}

/* define styles for the child circle div */
.variable-size .circle {
  position: absolute;
  background-image: url('https://i.imgur.com/2dxaFs9_d.webp?maxwidth=640&shape=thumb&fidelity=medium');
  background-position: center center;
  z-index: -1;
  border-radius: 50%;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  transition: all 0.5s ease;
  width: 0;
}

/* quickly adjust circle height to match current width */
.variable-size .circle:before {
  display: block;
  content: '';
  width: 100%;
  padding-top: 100%;
}

/* define styles for the demo window */
HTML,
BODY {
  height: 100%;
  min-height: 100%;
  background: black;
  position: relative;
  font-family: "Lucida Console", Courier, monospace;
}
<div class="variable-size">
  <textarea class="content" rows="1" placeholder="TYPE TEXT OR RESIZE ME &#8600;"></textarea>
  <div class="circle"></div>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


Check out the JSFiddle example here: https://jsfiddle.net/joshmoto/6d0zs7uq/

Answer №3

let canvas = document.getElementById("myCanvas");
let context = canvas.getContext("2d");
context.beginPath();
context.arc(100, 75, 50, 0, 2 * Math.PI);
context.stroke();

Reference: https://www.w3schools.com/

Answer №4

To achieve the desired layout, you can utilize flex display by adding empty flex-items around the inner div and adjusting their width using flex-basis.

Follow these steps:

.square {
  display: flex;
  justify-content: center;
  align-items: center;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  min-height: 100px;
  border-radius: 50%;
  background: black;
  background-size: 100% 100%;
  padding: 20px;
}

.content {
  width: 300px;
  min-height: 100px;
  background: tomato;
}

.emptyDiv {
  flex-basis: 120px
}
<div class="square">
  <div class="emptyDiv"></div>
  <div class="content">
    Hello!<br>
    <br><br><br>This has a variable height but fixed width<br><br><br>Hello
  </div>
  <div class="emptyDiv"></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

Creating an oval cutout shape using CSS in a div element

I am currently facing some challenges creating the design depicted in the image above, particularly with the oval shape. Let me provide an explanation: The menu bar is designed as a div with a subtle linear gradient that transitions from dark grey to a l ...

Exploring JSON data with Angular

I am struggling with searching JSON data using Angular. After following various tutorials online, I am now facing an issue where the JavaScript debugger in Chrome shows that the script is running but nothing is being displayed on the page. As a beginner, ...

Guide on using selenium webdriver (python) to choose, replicate, and insert all content within an element

Currently, I am faced with the task of transferring data from website A to website B as website A is soon going down. This includes not just text, but also images, hyperlinked text, and certain formatting requirements. Previously, the data transfer was don ...

Concealing specific sections of HTML content in a webview on the fly

I've been experimenting with a proof of concept feature to implement the ability to conceal certain parts of a web page loaded in a webview, but I seem to be encountering some issues... Within a UIWebview extension, I have something similar to this c ...

Interacting with jQuery mouse events on elements below the dragged image

I'm attempting to create a drag-and-drop feature for images using jQuery. While dragging, I generate a thumbnail image that follows the mouse cursor. However, this is causing issues with detecting mouseenter and mouseleave events on the drop target pa ...

Displaying images on the left side using CSS is causing issues in an ASP.NET project

Having trouble displaying a girl image in asp.net. I'm aiming for the following result: The problem is that the girl's face is not showing up correctly as shown below: This is the CSS I have created: .testimonialstilabel { background-image ...

The ClearInterval() function does not take effect instantly

I've implemented a Carousel with an auto-toggle feature using the setInterval() function to switch between tabs every 4 seconds. However, I now need to stop this automatic toggling when a specific tab is clicked. You can find the HTML and jQuery for ...

Steps to use a full-size image as the background for a <div> element

Here is the image_url I want to use: I would like to make this image the cover picture on the page linked below: However, the image is being cropped automatically. I prefer not to create a separate size for it. Is there a way to crop the image to maintai ...

Initiating CSS3 animations when the display changes

In an attempt to incorporate CSS3 animations for fading elements in during page load, I am faced with the challenge of setting the element to display: none; and then back to display: block;. My goal is to exclusively apply the CSS3 animation upon the init ...

Using TestCafe selectors to target a classname that has multiple matching nodes

I need help finding a TestCafe selector that can target an element with the same class name that appears multiple times in my HTML code. Here's what I have tried so far: https://i.sstatic.net/ZS691.png Despite trying various selectors, I have been u ...

Bootstrap 3 with a left sidebar menu featuring subtle ghosting borders for a sleek and modern

Hello there! I have a bootstrap 3 sidebar that seems to be causing some issues in IE 11. Specifically, I am encountering a strange ghosting effect on the border of the sidebar. When the page initially loads, only the bottom edge of the sidebar is visible. ...

Sending information from one ajax request to anotherORTransferring

Apologies for not including code in this post as I am currently working on a project in a car without internet access. Thankfully, I am using the amazing Stack Exchange app. Currently, I am facing a challenge where I need to work with two separate API cal ...

What is the process for incorporating sessionStorage information through an ajax request in Laravel?

Having just started working with ajax requests in Laravel, I find myself in a bit of a bind. I am struggling with inserting sessionStorage data into the database. For instance, consider the data stored in my sessionStorage: Key Value ============== ...

Is there a way to position the table to the right of the registration text boxes?

https://i.sstatic.net/Fh9Bk.jpg Is it possible to position the table using <div> elements? ...

Is there a way to retrieve the HTML code of a DOM element created through JavaScript?

I am currently using java script to generate an svg object within my html document. The code looks something like this: mySvg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); myPath = document.createElementNS("http://www.w3.org/2000/svg", ...

Converting HTML elements into a JSON object using jQuery

Is there a way to format an object like this from HTML using a button click? var Movie = [{id:"tt3783958", title:"La La Land", type:"Comedy, Drama, Music", year:"2016"}]; Can we then append the next object on the next button click with a format like this ...

Struggling to center divs in HTML and CSS but running into issues on mobile devices?

I've been facing some serious CSS issues lately! Currently, I have everything set up to center the #Box div, which works perfectly on all devices except for mobile browsers. The problem arises because the screen size of the mobile browser is too narr ...

Enrich your HTML using AngularJS

CSS <div class="container"> <section> <p>{{content}}</p> </section> </div> script.js (function () { var script = function ($scope){ $scope.content = "example"; } }()); I am currently ...

CKEditor not functioning properly when generated using AJAX and PHP in JavaScript file

I am facing an issue where I am using PHP and AJAX to generate a CKEditor textarea. The CKEditor JavaScript files are included in the main HTML file, and the PHP and AJAX functionalities are working correctly. However, when the form is displayed, the CKEdi ...

Tips for dimming a bootstrap modal while displaying a spinner

In the following example, you can open a modal, enter a message, and send it. The message will take 2 seconds to send. I have implemented a spinner to show while the message is sending, but I also want the background of the modal to be greyed-out during th ...