What is the best way to center the text vertically within a div element?

I recently designed a circular multi-step progress UI using HTML and CSS, but I encountered an issue when adding text underneath the circular icon. The line crossing the bar moved down because the circle's height increased based on the content length. How can I ensure that the line stays centered even as content is added?

Here are screenshots illustrating the issue:

Before adding the content:

https://i.sstatic.net/2JMb2.png

After adding the content:

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

I'm struggling with this CSS challenge and would appreciate any help or suggestions you can offer.

Check out the working demo to see the code in action.

App.js

import CheckIcon from "@mui/icons-material/Check";
import "./styles.css";

export default function App() {
  const steps = [1, 2, 3, 4, 5];
  return (
    <>
      <div class="container">
        <div class="progress-container">
          <div class="progress" id="progress"></div>
          {steps.map((val) => (
            <div>
              <div className={`circle ${val === 4 ? "active" : ""}`}>
                {val === 4 ? <CheckIcon sx={{ fontSize: "3rem" }} /> : null}
              </div>
              <div className="test">
                {val % 2 === 0
                  ? "Conservative"
                  : "Somewhat Conservative but it is okay"}
              </div>
            </div>
          ))}
        </div>
      </div>
    </>
  );
}

style.css:

@import url("https://fonts.googleapis.com/css?family=Muli&display=swap");

.container {
  text-align: center;
}

.progress-container {
  display: flex;
  justify-content: space-between;
  position: relative;
  max-width: 100%;
  width: 700px;
}

.progress-container::before {
  content: "";
  background-color: #767676;
  position: absolute;
  top: 50%;
  left: 0;
  transform: translateY(-50%);
  height: 4px;
  width: 100%;
  z-index: -1;
}

.progress {
  /* background-color: var(--line-border-fill); */
  position: absolute;
  top: 50%;
  left: 0;
  transform: translateY(-50%);
  height: 4px;
  width: 0%;
  z-index: -1;
  transition: 0.4s ease;
}

.circle {
  background-color: #fff;
  color: #999;
  border-radius: 50%;
  height: 85px;
  width: 85px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 3px solid #767676;
  transition: 0.4s ease;
  cursor: pointer;
  font-size: 20px;
}

.circle.active {
  border-color: #3769ff;
  background-color: #3769ff;
  color: #ffffff;
}

.test {
  max-width: 85px;
}

Results

** The length of the <hr/> tag decreases when resizing the screen. **

A link to the demo is provided in the comments section below.

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

Answer №1

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

Here is my solution for your desired outcome:

This is what I came up with: instead of using ::before, I used hr. In your specific case, the before element is centered within .progress_container, which includes the space taken up by the text. To center it within the circles instead, use top:calc(circle_height / 2 ).

Below are the changes I made to achieve this effect:

import CheckIcon from "@mui/icons-material/Check";
import "./styles.css";

export default function App() {
  const steps = [1, 2, 3, 4, 5];
  return (
    <>
      <div className="container">
        <div className="progress-container">
          <hr/>
         
          {steps.map((val) => (
            <div>
              <div className={`circle ${val === 4 ? "active" : ""}`}>
                {val === 4 ? <CheckIcon sx={{ fontSize: "3rem" }} /> : null}
              </div>
              <div className="test">
                {val % 2 === 0
                  ? "Conservative"
                  : "Somewhat Conservative but it is okay"}
              </div>
            </div>
          ))}
        </div>
      </div>
    </>
  );
}



CSS:


@import url("https://fonts.googleapis.com/css?family=Muli&display=swap");

.container {
  text-align: center;
}

.progress-container {
  display: flex;
  justify-content: space-between;

  position: relative;
  max-width: 100%;
  width: 700px;
}

hr{
  position:absolute;
  height: 4px;
  width: 90%;
  background: #000;
  top: calc(85px / 2);
  left: 50%;
  z-index: -1;
  transform: translate(-50%, -50%);

}

.progress {
  /* background-color: var(--line-border-fill); */
  position: absolute;
  left: 0;
  transform: translateY(-50%);
  height: 4px;
  width: 0%;
  z-index: -1;
  transition: 0.4s ease;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background: red;
}

.circle {
  background-color: #fff;
  color: #999;
  border-radius: 50%;
  height: 85px;
  width: 85px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 3px solid #767676;
  transition: 0.4s ease;
  cursor: pointer;
  font-size: 20px;
}

.circle.active {
  border-color: #3769ff;
  background-color: #3769ff;
  color: #ffffff;
}

.test {
  max-width: 85px;
}



*** Impact of the .container width on mobile view ***

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

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

Tips for including assisting text in the date field with Material UI

Behold, my component definition: <DateField name={formElement.name} type="date" label={formElement.name} onChange={(date) => formik.setFieldValue(formElement.name, date)} value={formik.values[formElement.name] ...

Slider in Material-UI fails to drag while loading component from a switch statement

I have been working on a new feature that involves using radio buttons to manipulate the state and determine which components should be active. It seems like everything is set up correctly, but for some reason, the slider won't slide smoothly - you ha ...

Utilize background-size:cover and incorporate text in a horizontally scrolling webpage

Struggling to create a minimalist HTML layout with a horizontal scrollbar, featuring a large image on the left and a lengthy text with columns on the right? I suspect the issue lies in the implementation of position:relative with float, as well as position ...

Colorful layers of nested divs

I need help changing the background-color of the parent div behind the children ones. I want it to be darker like in this image. Here's my HTML: <div class="main"> <div class="sub"> </div> </div> And here is my CSS: ...

Utilize a list of Data Transfer Objects to populate a dynamic bar chart in recharts with

I received a BillingSummaryDTO object from a Rest API using Typescript: export interface BillingSummaryDTO { paid?: number, outstanding?: number, pastDue?: number, cancelled?: number, createdAt?: Moment | null, } export async function ...

The font styles in IE are failing to render properly following the disabling of caching in Node JS

Why are the CSS fonts not working in Internet Explorer after disabling cache in Node JS? After a user navigates to a page and then clicks the back button to return to the previous page, the font styles are not rendered properly in IE 11. The code 'k ...

Material-UI - JSS style order issue

I am facing an issue where the JSS styles from my MUI component library (Styles A) are taking precedence over the styles provided by a consumer's website (Styles B). The intended behavior is for Styles A to be overwritten by Styles B. Consider this ...

"Organize with the power of Drag and Drop - Update array field with custom

Currently implementing React Beautiful Dnd for item reordering. Everything is functioning smoothly, but within my onDragEnd function, I have the following logic: function onDragEnd(result) { const modifiedItems = [...customgearUpdate]; const [remo ...

Issue with React routing: When passing id params in the URL using history.push, it is returning undefined

Struggling with using history.push in an onClick event to pass user id to a Profile page component, but the uuid params in the URL are showing up as undefined. Feeling stuck at this point. I also need to include all other props obtained from the Random Us ...

Efficient Techniques for Concealing and Revealing Navigation Menus using HTML, CSS, and JavaScript

I need help making the menu icon toggle the navigate menu between showing and hiding when clicked on the top right corner of the screen. For better understanding, here is an accompanying image: https://i.stack.imgur.com/oy6d9.png However, the current co ...

Data retrieval from client-side fetch request results in a corrupted file upon download

I'm facing an issue while attempting to fetch a file using a GET request and download it directly in the browser. However, after the download is complete and I try to open the file, it seems to be corrupted. Strangely, only .txt files are opening corr ...

Typical ClassIdentifier using Material UI

I have come across similar questions and answers, but due to the MaterialUI update where @mui/styles is deprecated, I didn't fully grasp the concept. As per the MUI docs, we can create custom styles using the sx prop, like this: <Typography varian ...

Utilize Bootstrap columns to maximize vertical space efficiency

I recently came across a bootstrap layout like this: https://i.sstatic.net/VXBCF.png In this setup, there is a single .row that contains 8 .col-lg-3 divs. However, I noticed that there is excessive vertical whitespace present, which not only looks undesi ...

A guide to efficiently eliminating UI elements with React JS

Struggling to find clear instructions on removing UI components in React? Take a common scenario: there's a login form that should disappear after the user submits it. How can this be achieved? Although unmountComponentAtNode exists, it seems like it ...

What is the best method for including the API key as a query parameter in a GET request when using Axios in a React application for the Bing Web Search

I'm currently working on implementing a search bar using the Bing Web API, but I'm facing challenges in passing the API key and user input from the search bar into the GET request using Axios. Any detailed guidance on how to achieve this would be ...

I am experiencing issues with resizing my image within the CSS flexbox layout

I attempted to create a flex container for my jpg file in HTML but ran into an issue. Even after adding image dimensions in CSS, the image remained the same size with no changes at all. </head> <div class="flex-container"> ...

How can we prevent components from rendering in React when their state or props have not changed?

I encountered a problem in my project where I have a main component that serves as the parent component of my project. Inside this main component, I have defined routes for other components and directly imported some components like a Side Navbar and Login ...

Material-UI: Issue with Bottom Navigation Placement on Page

Currently, I'm working on implementing the Bottom Navigation feature. However, I am encountering an issue where it is not displaying at the bottom of the page as expected. Instead, it seems to be positioned relative to the content above it in the DOM. ...

What is the best strategy for managing a sizable react application using react-query?

Since diving into React with functional components and react-query, I've been facing some confusion on how to properly organize my components. Typically, I design components by having a top-level component handle all data access and pass data down to ...

Create the columnHeader to match the width of the CSS column

Here's what I attempted: http://codepen.io/helloworld/pen/BcjCJ I aim for each column to have the same width as the column header visually. Currently, a slight difference in width exists between the column header and the actual column. Refer to the ...