What is the best way to align text at the center of a circular animation?

I stumbled upon this fascinating animation and I'm looking to incorporate it into my project. However, I'm facing a challenge in centering text inside the circle without resorting to using position absolute.

My goal is to have the text with the class name "text-to-center" positioned inside the circle.

Check it out on Codepen

<div class="outer-circle">
  <span class="text-to-center">0:00:00</span>
  <div class="wrapper">
    
    <div class="breath">
      <div class="flare1"></div>
      <div class="flare2"></div>
    </div>
  </div>
</div>
@keyframes pulse {
  20% {
    transform: scale(1);
  }
  40% {
    transform: scale(0.6);
  }
  50% {
    transform: scale(0.6);
  }
  60% {
    transform: scale(0.6);
  }
  80% {
    transform: scale(1);
  }
}

@keyframes rotate {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

body {
  background-color: #000215;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  overflow: hidden;
  color: #fff;
  
  .outer-circle {
    width: 300px;
    height: 300px;
    border-radius: 150px;
    box-shadow: 0 0 5px 15px rgba(#2F2B8C, 0.1);
    background-image: radial-gradient(#2F2B8C00, #2F2B8C00 50%, #2F2B8C33 90%);
  }
  
  .wrapper {
    animation: pulse 8s cubic-bezier( 0.7, 0, 0.3, 1 )  infinite;
    position: relative;
    
    .breath {
      width: 300px;
      height: 300px;
      border-radius: 150px;
      position: relative;
      background-color: #000215;
      animation: rotate 16s linear infinite;
      
      &::before {
        content: '';
        position: absolute;
        top: 0; 
        right: 0; 
        bottom: 0; 
        left: 0;
        z-index: -1;
        margin: -3px;
        border-radius: inherit;
        background: linear-gradient(135deg, #D904B5, #2F2B8C);
        box-shadow: 0 0 14px 15px rgba(#2F2B8C, 0.3);
      }
      
      &::after {
        content: "";
        display: block;
        position: relative;
        width: 300px;
        height: 300px;
        border-radius: 150px;
        background-color: #000215;
      }
      
      .flare1 {
        width: 240px;
        height: 240px;
        content: "";
        display: block;
        border-radius: 50px;
        background-image: radial-gradient(#D904B563, #D904B500 60%);
        position: absolute;
        left: -70px;
        top: -70px;
        z-index: -1;
      }

      .flare2 {
        width: 240px;
        height: 240px;
        content: "";
        display: block;
        border-radius: 50px;
        background-image: radial-gradient(#2F2B8C63, #D904B500 60%);
        position: absolute;
        right: -70px;
        bottom: -70px;
        z-index: -1;
      }
    }
  }
}

.text-to-center {
 // Trying to figure out how to get this centered inside the circle without using position absolute
}

Is there a way to achieve this effect without relying on position absolute?

Answer №1

Here is a CSS code snippet you can try:

@keyframes pulse {
  20% {
    transform: scale(1);
  }
  40% {
    transform: scale(0.6);
  }
  50% {
    transform: scale(0.6);
  }
  60% {
    transform: scale(0.6);
  }
  80% {
    transform: scale(1);
  }
}

@keyframes rotate {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

body {
  background-color: #000215;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  overflow: hidden;
  color: #fff;

  .outer-circle {
    width: 300px;
    height: 300px;
    border-radius: 150px;
    box-shadow: 0 0 5px 15px rgba(#2F2B8C, 0.1);
    background-image: radial-gradient(#2F2B8C00, #2F2B8C00 50%, #2F2B8C33 90%);
    position: relative;
  }

  .wrapper {
    animation: pulse 8s cubic-bezier(0.7, 0, 0.3, 1) infinite;
    position: relative;

    .breath {
      width: 300px;
      height: 300px;
      border-radius: 150px;
      position: relative;
      background-color: #000215;
      animation: rotate 16s linear infinite;

      &::before {
        content: '';
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        z-index: -1;
        margin: -3px;
        border-radius: inherit;
        background: linear-gradient(135deg, #D904B5, #2F2B8C);
        box-shadow: 0 0 14px 15px rgba(#2F2B8C, 0.3);
      }

      &::after {
        content: "";
        display: block;
        position: relative;
        width: 300px;
        height: 300px;
        border-radius: 150px;
        background-color: #000215;
      }

      .flare1 {
        width: 240px;
        height: 240px;
        content: "";
        display: block;
        border-radius: 50px;
        background-image: radial-gradient(#D904B563, #D904B500 60%);
        position: absolute;
        left: -70px;
        top: -70px;
        z-index: -1;
      }

      .flare2 {
        width: 240px;
        height: 240px;
        content: "";
        display: block;
        border-radius: 50px;
        background-image: radial-gradient(#2F2B8C63, #D904B500 60%);
        position: absolute;
        right: -70px;
        bottom: -70px;
        z-index: -1;
      }
    }
  }
}

center {
    height: 100%;
    position: absolute;
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
}

.text-to-center {
    position: relative;
    z-index: 9;
}
<div class="outer-circle">
        <center><span class="text-to-center">0:00:00</span></center>
        <div class="wrapper">

          <div class="breath">
            <div class="flare1"></div>
            <div class="flare2"></div>
          </div>
        </div>
      </div>

Answer №2

Considering your request to avoid using position: absolute.

You can achieve center alignment by adding display:flex to the span in your text, and adjusting the top property as needed:

.text-to-center {
    top: 160px;
    z-index: 200;
    position: relative;
    display: flex;
    justify-content: center;
}

Here is the working code example:

@keyframes pulse {
  20% {
    transform: scale(1);
  }
  40% {
    transform: scale(0.6);
  }
  50% {
    transform: scale(0.6);
  }
  60% {
    transform: scale(0.6);
  }
  80% {
    transform: scale(1);
  }
}

@keyframes rotate {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

body {
  background-color: #000215;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  overflow: hidden;
  color: #fff;
}

body .outer-circle {
  position: relative;
  width: 300px;
  height: 300px;
  border-radius: 150px;
  box-shadow: 0 0 5px 15px rgba(47, 43, 140, 0.1);
  background-image: radial-gradient(#2f2b8c 0, #2f2b8c 0 50%, #2f2b8c 33 90%);
}

body .wrapper {
  animation: pulse 8s cubic-bezier(0.7, 0, 0.3, 1) infinite;
  position: relative;
}

body .wrapper .breath {
  width: 300px;
  height: 300px;
  border-radius: 150px;
  position: relative;
  background-color: #000215;
  animation: rotate 16s linear infinite;
}

body .wrapper .breath::before {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: -1;
  margin: -3px;
  border-radius: inherit;
  background: linear-gradient(135deg, #d904b5, #2f2b8c);
  box-shadow: 0 0 14px 15px rgba(47, 43, 140, 0.3);
}

body .wrapper .breath::after {
  content: "";
  display: block;
  position: relative;
  width: 300px;
  height: 300px;
  border-radius: 150px;
  background-color: #000215;
}

body .wrapper .breath .flare1 {
  width: 240px;
  height: 240px;
  content: "";
  display: block;
  border-radius: 50px;
  background-image: radial-gradient(#d904b5 63, #d904b5 0 60%);
  position: absolute;
  left: -70px;
  top: -70px;
  z-index: -1;
}

body .wrapper .breath .flare2 {
  width: 240px;
  height: 240px;
  content: "";
  display: block;
  border-radius: 50px;
  background-image: radial-gradient(#2f2b8c 63, #d904b5 0 60%);
  position: absolute;
  right: -70px;
  bottom: -70px;
  z-index: -1;
}

.text-to-center {
  top: 160px;
  z-index: 200;
  position: relative;
  display: flex;
  justify-content: center;
}
<div class="outer-circle">
  <span class="text-to-center">0:00:00</span>
  <div class="wrapper">
    <div class="breath">
      <div class="flare1"></div>
      <div class="flare2"></div>
    </div>
  </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

Trouble Arising from Regional Settings in my Hybrid App Developed with CapacitorJS and Vue.js

Issue with capacitor app input Correct input in chrome app I'm facing a problem related to regional settings in my mobile application, developed using CapacitorJS and Vue.js 2. The datetime-local control is appearing in a language that isn't the ...

Populate the table with JSON object information

I've structured a table as follows: <div class="row"> <div class="row"> <table class="table table-bordered table-striped tree-grid"> <thead class="text-primary"> <tr> <th> ...

What is the trick to showing text underneath a font awesome icon?

My HTML code contains font awesome icons, and I'm looking to have text appear below each icon instead of next to it. Currently, the text is displayed midway to the right of each icon. <div class="icons"> <span class="fa-stack f ...

What is the process for executing a Js file on a website?

I am looking to automate some tasks on a website that I do not own. Specifically, I need to automatically fill out a form and perform certain clicking actions. Can JavaScript be used for this purpose? I am unsure how to run a .js file on a site without the ...

What is the best way to align a dropdown menu and a textbox on the same line

I have recently been working on a search bar that includes a Dropdown for Location and a Textbox for Search. Prior to implementing bootstrap, these elements were displayed in a single line. However, after applying bootstrap, they are now stacked vertically ...

Text Parallax Effect

For my website, I am interested in incorporating a unique parallax effect. Instead of just fixing a background image and allowing scrolling over it, I want to apply this effect to all of the content on my site. The website consists of a single page with m ...

Has the user successfully authenticated with Google?

Possible Repetition: How to verify if a user is logged into their Google account using API? I'm working on a website that displays a Google Calendar. My query is: Can I determine whether a user is currently logged into a Google Account? If it&ap ...

Looking to minimize the amount of HTML code in Angularjs by utilizing ng-repeat

Working with some HTML <tr class="matrix_row" ng-repeat="process in matrixCtrl.processes | filter : { park: parentIndex } track by $index"> <td class="properties" ng-click="dashboardCtrl.currParam=0; dashboardCtrl.currentProcess=process"> ...

Creating a Bootstrap 4 table that utilizes the full width while maintaining responsiveness

Is it feasible to implement a table-responsive solution that adjusts column width based on the length of data within each column, while still allowing the thead to occupy the entire canvas width? For Example: (the last column with no content should take u ...

Turn off hover effect for MUI DataGrid

I'm having trouble figuring out how to disable the hover effect on a row in the MUI Datagrid. I've searched through the API documentation but couldn't find a straightforward solution. Any suggestions on how to achieve this? <DataGrid ...

Using an HTML element to pass a variable into a replace function

I am looking to highlight a 'SearchString' by replacing it with <span style="background-color: yellow">SearchString</span> within a targetString. The SearchString varies, so I am wondering how I can make this happen. This is what I ...

Modifying the WP FlexSlider plugin to eliminate the previous and next side panels

Is there a way to either reduce the width of the slider's prev/next sides or remove these panels while keeping the arrows to cycle through slides? These elements appear to be within ul.flex-direction-nav. I attempted using ul.flex-direction-nav { dis ...

Problem with applying ng-class directive in AngularJS

I am currently developing an application using AngularJs and Bootstrap. My goal is to display the title of a 'scenario' with different styling based on its status, along with a specific icon. Initially, I attempted the following approach: <s ...

Having issues with Tailwind classes not being applied properly on dynamically generated pages in Gatsby-node

Currently, I am working on building dynamic pages using gatsby-node. The templates for these pages are stored in the templates/ directory. However, I have run into an issue where I cannot utilize tailwind classes within these templates unless they are al ...

Extracting text from an HTML file and passing it to an Express.js server: A beginner

Currently, I'm attempting to retrieve the values from an HTML text field and store them in variables. I require HTML to capture these values and return the response within the .html file. HTML: <body> <form> ...

Leverage variable as an expression when utilizing ng-include

Here is an example of working code: <div ng-include src="'Test.html'"></div> However, this code does not work: <div ng-include src="ctrl.URL"></div> (When ctrl.URL is set to "Test.html"). I have also tried setting it t ...

Tips for improving the focus of the bootstrap datetime picker?

I have integrated the Bootstrap datetime picker (bootstrap-datetimepicker.min.js) into my code. Within the DIV tag, I have included the class="modal fade" to open the first popup. In the first popup, there is a datetime picker. When clicking on the picker ...

Displaying and concealing information using AngularJS

I am attempting to switch between two different content views using angular. Currently, the page initially displays no content and only switches between the two views after clicking on an option. What I would like it to do is display the first view upon l ...

JavaScript code to generate a random color for the box shadow effect

Recently, I developed a function that generates random divs containing circles. The function randomly selects a border color for each circle, and this feature is functioning correctly. To enhance the appearance, I decided to add a box shadow to the circl ...

The SVG animation is reversing and decreasing in size from the bottom

Feeling lost, I spent a day searching without success. I have a project in full Vuejs and I thought using Svg would be easy and fun, but I can't figure out why the image resizes when playing an animation. The bottom of the svg seems to resize and get ...