Placing markers on a straight path

Struggling to create a CSS component where the first and last points don't align properly with the ends of the line.

This component should be able to handle any number of points (between 1 and 4) without relying on flexbox.

I have a React component generating HTML like this:

<div class="row">
  <div class="col first" style="width:33%">
    <div class="marker complete"></div>
    <label>Feedback</label>
  </div>
  <div class="col" style="width:33%">
    <div class="marker partial"></div>
    <label>Observation</label>
  </div>
  <div class="col last" style="width:33%">
    <div class="marker review"></div>
    <label>Documentation</label>
  </div>
</div>

The JavaScript calculates column sizes before rendering, and I'm currently centering content in each column in my Codepen demo.

To position the end items, I've used the `first` and `last` classes for relative positioning, but when the screen size changes, the line edges start showing behind the points. Any suggestions for a better layout approach?

Answer №1

To create a horizontal bar between circles, one approach could be to define the row as display: table-row, and then utilize a pseudo element for the bar. However, a challenge arises as CSS and HTML alone cannot determine the precise position of the first and last circle within the container. Consequently, achieving a full-width effect becomes difficult.

Alternatively, you can use the labels as anchor points for the pseudo elements since they always span the entire column width, providing clear reference points.

The proposed solution, available at this link, is compatible with IE9 and relies on using calc and after. (If preferred, transform: translate can replace calc.)

The concept involves utilizing a table row that dynamically adjusts its size and leveraging the labels to construct the progress bar.

label:after {
  content: "";
  height: .5em;
  background: #e2e2e2;
  width: 100%;
  position: absolute;
  top: calc((100% - 1.5em) / 2); /* Adjusted for text and bar height */
  left: 0;
  z-index: -1;
}

.first label:after, .last label:after {
  width: 50%;
}

.first label:after {
  left: auto; 
  right: 0;
}

.single label:after {content: none;}

Answer №2

Here is the solution you've been searching for.

<div class="row">
  <div class="col" style="width:33%">
    <div class="marker marker1 complete"></div>
    <label>Feedback</label>
  </div>
<div class="col2" style="width:33%">
    <div class="marker marker2 partial"></div>
    <label>Observation</label>
</div>
<div class="col3" style="width:33%">
   <div class="marker marker3 review"></div>
     <label>Documentation</label>
   </div>
</div>

Check out the code here

*If JavaScript is allowed, conditions can be added based on number and word length to adjust marker indentations.

I utilized display blocks, margins, and secondary marker classes for each block.

Answer №3

.row {
  display: table;
  margin: 0 auto;
  position: relative;
  width: 100%;
}
.col {
  display: table-cell;
  width: 33%;
  text-align: center;
}
.marker {
  width: 30px;
  height: 30px;
  background-color: lightgray;
  border-radius: 30px;
  margin: 0 auto;
}
.complete {
  background-color: blue;
}
.partial {
  background-color: blue;
  box-sizing: border-box;
  border: 8px solid lightgray;
}
.review {
  background-color: lightblue;
}
.col:not(:last-child) > .marker:after {
  content: '';
  display: inline-block;
  width: 67%;
  height: 0;
  border: 3px solid lightgray;
  position: absolute;
  left: 16.5%;
  top: 12.5px;
  z-index: -10;
}
/* ------------------------------------------- */

.wrapper {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 100px;
}
.point {
  height: 30px;
  background-color: lightgray;
  border-radius: 30px;
  flex: 0 0 30px;
  position: relative;
}
.line {
  height: 0;
  border: 3px solid lightgray;
  flex: 1 0;
}
.blue {
  background-color: blue;
}
lightblue {
  background-color: lightblue;
}
.border {
  background-color: lightgray;
  background-image: radial-gradient(at center center, blue 0, blue 8px, transparent 8px, transparent 100%);
}
.point label {
  position: absolute;
  left: -50%;
  top: 100%;
  text-align: center;
}
<h1>Non flex</h1>
<div class="row">
  <div class="col first">
    <div class="marker complete"></div>
    <label>Feedback</label>
  </div>
  <div class="col">
    <div class="marker partial"></div>
    <label>Observation</label>
  </div>
  <div class="col last">
    <div class="marker review"></div>
    <label>Documentation</label>
  </div>
</div>
<h1>Flex</h1>
<div class="wrapper">
  <div class="point blue">
    <label>Feedback</label>
  </div>
  <div class="line"></div>
  <div class="point blue border">
    <label>Observation</label>
  </div>
  <div class="line"></div>
  <div class="point lightblue">
    <label>Documentation</label>
  </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

Do you know of a solution to fix the Stylelint error regarding semicolons when using CSS variables?

React.js Css in JS(Emotion) The components above are part of this setup. Here is the configuration for Stylelint: module.exports = { extends: [ "stylelint-config-standard", "./node_modules/prettier-stylelint/config.js", ], ...

Create a Bootstrap div containing a button that adjusts to different screen sizes on the

Struggling with an issue in Bootstrap on how to create an input group with responsive content and a button on the right side. I want the button to always be on the right side and also responsive. I attempted to achieve this with the code below, but it does ...

unable to retrieve data using ajax

Having some trouble with my ajax code that is supposed to print values: success: function(returndata) { $('#first').html("<div id='first' class='progress-bar progress-bar-primary' role='progressbar' aria-valu ...

A checkbox placed within an anchor tag

Here is some code that I have: <a href class="dropdown-toggle"> <input type="checkbox" ng-model="test.checked"> <span class="fa fa-angle-down"></span> </a> When I click on the above code, I want the chec ...

Adding an id to a ul tag using JavaScript

I am trying to dynamically add an ID called "myMenu" using JavaScript to a ul element for a search filter. Unfortunately, I am unable to directly access the ul tag to change it, so I need to do it via JavaScript. As I am new to JavaScript, I am looking t ...

Looking to add a dynamic divider between two columns that can be adjusted in width by moving the mouse left and right?

If you're looking for an example of two columns adjusting their width based on mouse movement, check out this page from W3Schools. I'm trying to implement this feature in my React app, but I'm unsure of how to proceed. Below is the JSX code ...

CSS designed for small-screen laptops is also being utilized on iPads running Safari

To specifically target the iPad/Safari browser and accommodate some minor differences in appearance compared to windows/linux browsers, we are implementing the following HTML meta tag and style query: <meta name="viewport" content="width=device-width, ...

Utilize Bootstrap-Vue to ensure that an element expands to occupy the available space

In my Bootstrap-Vue application, I have set up the following hierarchy: <b-navbar.../> <b-container > <b-row align-v="center" style="min-height:100vh"> <b-col style="align-items:center"> <h1>404 Error&l ...

Coding with Angular 4 in JavaScript

Currently, I am utilizing Angular 4 within Visual Studio Code and am looking to incorporate a JavaScript function into my code. Within the home.component.html file: <html> <body> <button onclick="myFunction()">Click me</button> ...

Which slider was featured in the unity3d.com/5 website?

While browsing the internet, I came across the website and was intrigued by the slider effect featured in the "graphics" section. I am eager to figure out how to replicate that stunning visual effect. ...

Block entry to HTML files unless the user has logged in utilizing PHP sessions

I have been working on implementing a verification process to check if a user is logged in when accessing a specific HTML file. When a user tries to access something.html without being logged in, I would like to redirect them to index.php and restrict acc ...

What are some ways in which I can utilize the Ember Handlebars helper?

Similar Question: Using logical operators in a Handlebars.js {{#if}} statement Below is the code snippet provided: {{#each dataArray}} <li>{{#isTrue idVal1 idVal2}} display some text1 {{else}} display some text2 {{/isTrue}} & ...

Access specific data from a jQuery event

How can I retrieve the value of a custom attribute called itemID in order to include it in the URL just like I do with id? Here is the JavaScript code: <script type="text/javascript"> $(document).ready(function(){ $('.eventImage').cl ...

Issue with readonly is preventing the ability to alter the font color of the input

I need to change the font color of a disabled input. When it is disabled, it appears gray and I want it to be black instead. I attempted to use readonly but that did not have the desired effect, and now the input is showing [object Object]. Below is my HTM ...

Is there an easy method to verify if the local storage is devoid of any data?

Query is named aptly; seeking to verify in a conditional statement. ...

Tips for extracting title and image from someone else's blog posts to share on your own website

Currently, I am in the process of creating a website where I can showcase my personally curated content. I have been struggling to figure out how to seamlessly integrate this content into my site without relying on an API. My initial idea was to manually ...

Ways to execute a function when clicking on a date using HTML 5 datepicker input type

How can I call a function in angular js when a date is selected from an html5 date-time picker using a mouse click? I need help with this. Here is the HTML code: <div class="col-lg-4"> <input class="form-control" type="datetime" date-time auto ...

Can WebGL be configured to render offscreen without its canvas being directly connected to the DOM?

Searching for an answer to what I believed would be a simple question has proven to be quite challenging. My goal is to utilize WebGL for image processing and generation tasks, with the intention of working offscreen. Specifically, I aim for WebGL to rende ...

Padding-left in InfoBox

Currently, I am in the process of developing a map using Google Maps API3 along with the InfoBox extension available at this link I have successfully implemented an overall padding to the Infobox using the following code snippet: var infoOptions = { disa ...

What is the best way to horizontally align an inline div using CSS?

Is it possible to apply CSS to center an inline div that has an unknown width? Note: The width of the div cannot be specified beforehand. ...