Positioning bar chart columns and text using CSS

My component generates HTML for a simple bar chart, with the height and background color computed within the component. Everything functions correctly, but I am facing an issue where long text causes displacement of the bar above it.

Another problem is that the width of the bars seems to depend on the width of the text, but that's a topic for another discussion.

When the viewport is wide enough, the chart looks like this:

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

However, when the viewport is smaller (this is the issue I want to address): https://i.sstatic.net/Xb73m.png

I believe there needs to be some offsetting for the rest of the bars and their labels?

<ul class="flex gap-3 items-end">
    <li class="flex flex-col flex-grow gap-1 content-center">
        <span style="height:42.666666666666664px;background-color:#d73027" title="Apple - 10">
        </span>
        <div class="text-sm text-center">Apple</div>
    </li>
    <li class="flex flex-col flex-grow gap-1 content-center">
        <span style="height:128px;background-color:#f46d43" title="Very Long Banana - 30">
        </span>
        <div class="text-sm text-center">Very Long Banana</div>
    </li>
    <li class="flex flex-col flex-grow gap-1 content-center">
        <span style="height:64px;background-color:#fdae61" title="Orange - 15">
        </span>
        <div class="text-sm text-center">Orange</div>
    </li>
    <li class="flex flex-col flex-grow gap-1 content-center">
        <span style="height:106.66666666666667px;background-color:#fee08b" title="Grape - 25">
        </span>
        <div class="text-sm text-center">Grape</div>
    </li>
</ul>

Answer №1

Many solutions were suggested in the comments, and this is just one of them.

Edit: Check out @MagnusEffect's response for a simpler alternative.


If you prefer to maintain your current layout using an unordered list as a container for both bars and labels, consider wrapping all bars with a fixed-sized div for vertical alignment. Alternatively, you could split the bars and labels into two separate rows with equally sized items. I used absolute positioning within the wrapper divs for item placement; flexbox can also be utilized here.

You can utilize flex-basis alongside word-wrap to ensure equal widths across flex items. Using some form of overflow property for text overflow can serve as an alternative to word-wrap.

<!doctype html>
<html>

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script src="https://cdn.tailwindcss.com"></script>
</head>

<body>
  <ul class="flex gap-3 items-start" style="width: 270px; resize: both; overflow: auto; border: 1px solid black">
    <li class="flex flex-col basis-0 flex-grow gap-1">
      <div class="relative" style="height: 128px;">
        <span class="absolute w-full bottom-0" style="height:42.666666666666664px;background-color:#d73027" title="Apple - 10"></span>
      </div>
      <div class="text-sm text-center" style="word-wrap: anywhere;">Apple</div>
    </li>
    <li class="flex flex-col basis-0 flex-grow gap-1">
      <div class="relative" style="height: 128px">
        <span class="absolute w-full bottom-0" style="height:128px;background-color:#f46d43" title="Very Long Banana - 30"></span>
      </div>
      <div class="text-sm text-center" style="word-wrap: anywhere;">Very Long Banana</div>
    </li>
    <li class="flex flex-col basis-0 flex-grow gap-1">
      <div class="relative" style="height: 128px">
        <span class="absolute w-full bottom-0" style="height:64px;background-color:#fdae61" title="Orange - 15"></span>
      </div>
      <div class="text-sm text-center" style="word-wrap: anywhere;">Orange</div>
    </li>
    <li class="flex flex-col basis-0 flex-grow gap-1">
      <div class="relative" style="height: 128px">
        <span class="absolute w-full bottom-0" style="height:106.66666666666667px;background-color:#fee08b" title="Grape - 25"></span>
      </div>
      <div class="text-sm text-center" style="word-wrap: anywhere;">Grape</div>
    </li>
  </ul>
</body>

</html>

Answer №2

When utilizing the items-end class, it aligns the object using the end (text).

To adjust this, switch to the items-baseline class and include flex-row in the <ul>.

The updated code will look like this:

<ul class="flex gap-3 flex-row items-baseline">
        <li class="flex flex-col flex-grow gap-1 content-center">
            <span style="height:42.666666666666664px;background-color:#d73027" title="Apple - 10">
            </span>
            <div class="text-sm text-center">Apple</div>
        </li>
        <li class="flex flex-col flex-grow gap-1 content-center">
            <span style="height:128px;background-color:#f46d43" title="Very Long Banana - 30">
            </span>
            <div class="text-sm text-center">Very Long Banana</div>
        </li>
        <li class="flex flex-col flex-grow gap-1 content-center">
            <span style="height:64px;background-color:#fdae61" title="Orange - 15">
            </span>
            <div class="text-sm text-center">Orange</div>
        </li>
        <li class="flex flex-col flex-grow gap-1 content-center">
            <span style="height:106.66666666666667px;background-color:#fee08b" title="Grape - 25">
            </span>
            <div class="text-sm text-center">Grape</div>
        </li>
    </ul>
</div>

For a visual demonstration, you can view it here on tailwind play

Answer №3

It is recommended to utilize the VW method for adding CSS to text elements. For instance, you can set the font size using a value like 16vw;

Here is a helpful reference link that you may want to explore: https://css-tricks.com/viewport-sized-typography/

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

Sliding Feature

Can someone assist me with implementing a jQuery half slide function from left to right? Please check out the following URL for more information: http://jsfiddle.net/prabunivas/Fy9Hs/2/ <div> <div id="col1" style="float:left"> &l ...

The visibility of overflow-y does not seem to be working properly when overflow-x is

https://i.sstatic.net/hihjC.png .iati-list-table { overflow-x: auto; overflow-y: visible; } When I apply overflow-visible, a scroll bar appears. But when I use overflowy-hidden, the tooltip is cropped. How can I set it so that overflow x is auto a ...

Angular package that includes horizontal scrolling functionality with arrow buttons

Currently seeking an Angular 2-6 package featuring a horizontal image scroll with arrows, similar to the functionality on Airbnb: Any suggestions or recommendations are greatly appreciated – thank you! ...

The design of iOS7 Safari becomes distorted when the orientation changes and an input field is in focus

It appears that there is a major issue in iOS7 on iPhone and iPad devices, and possibly on other versions as well. When you focus on an input field, causing the keyboard to open, the layout experiences a severe and irreversible disruption upon changing or ...

Ensuring the validity of a signed cookie in Node using Express

I'm currently working on incorporating signed cookies in Node's express module. I've reviewed the documentation, but I'm struggling to understand how to properly verify them. My understanding is that verification must occur on the serve ...

Preserving the selected options in a dynamically populated dropdown list after submitting a form using php

I am attempting to preserve form values even after submitting the form. document.getElementById('start_date').value = "<?php echo $_POST['start_date'];?>"; document.getElementById('end_date').value = "<?php echo $_P ...

Error encountered: A missing semicolon was detected before a statement while executing code within a for

Although this question may have already been asked, I am struggling to understand why it is not working as expected. I simply want to increment the markers array within a for loop and then add each marker to the vector source using vectorSource.addFeature ...

Tips for positioning a div alongside its parent div

I have a unique setup with two nested divs that are both draggable. When I move the parent div (moveablecontainer), the child div (box.opened) follows smoothly as programmed. Everything works well in this scenario. However, when I resize the browser windo ...

Getting the scroll position of a Vuetify v-table: A guide

Utilizing the Vuetify v-table component to handle a large amount of data, I am seeking a way to read the current scroll position (both horizontally and vertically) of the table during certain actions. Here is what I have attempted thus far: Playground < ...

Create a line break in an alert using PHP

<?php function alert($msg) { echo "<script type='text/javascript'>alert('$msg');</script>"; } if(array_key_exists('btnRegisterAdmins', $_POST)) { $fname = $_POST['FirstName']; $lname=$_POST['La ...

Ajax TabContainer mysteriously vanishes during Postback

I'm currently working on a GIS web application using C# ASP.net. Within my project, I have an Ajax TabContainer that houses multiple TabPanels containing various elements like a map window and scale bar from the ESRI WebAdf toolkit. Below is a simpl ...

Could this be the most straightforward and versatile method for vertically centering text inside a block element?

Discovering something new in the world of coding is always exciting: HTML: <div>Vertically Centered Text<span></span></div> CSS: div { height: 100px; /* adjust as needed */ } div > span { display: inline-block; v ...

Adjusting the line-height in CSS dynamically based on the length of characters using jQuery

I am facing an issue with the Twitter widget on my website where our company's latest tweet sometimes gets cut off if it exceeds a certain length. I want to dynamically adjust the line-height CSS property of the element based on the tweet's chara ...

Ways to restrict input text to a specific set of values

When using an input text form, I need to ensure that users only insert values ranging from 1 to 10. However, my attempts to utilize a mask for customization have resulted in allowing values higher than 10. How can I restrict the input to only be allowed b ...

A helpful tip for dynamically adjusting the canvas size is to utilize its height and width attributes to resize it whenever it undergoes a change

I am encountering an issue with the canvas element in my code. The canvas is supposed to update whenever its containing div is resized. window.addEventListener('resize',function() { let mapwidth = $('.canvas').attr("width") l ...

How can a JQuery slideshow be programmed to only iterate once?

Looking to create a slideshow that transitions between images every two seconds? Check out the code snippet below: HTML: <div class="fadeIn"> <img src="img/city.png" class="remimg" id="city"> <img src="img/shop.png" class="remimg" ...

ag-Grid incorporating new style elements

For my Angular application, I have a simple requirement of adding a CSS class when a row expands or collapses to highlight the row. I attempted to use gridOptions.getRowClass following the documentation at https://www.ag-grid.com/javascript-grid-row-styles ...

problem with css3 webkit transform rotation

After using jQuery to append my signpost div to the DOM, I encountered an issue where its width and height were not being affected by webkit transforms. When I removed the transforms, the div displayed correctly. My goal is to append the div and then anima ...

How can TailwindCSS be used to wrap a nested flexbox at a specific viewport?

Utilizing TailwindCSS, I have the following code snippet: <div class="box-border flex w-auto flex-row gap-2 rounded-2xl border p-4 my-4 mx-4"> <div class="grow-0"> <div class="flex h-full flex-col items-center ...

Discovering the page load times of web elements on a website with the help of Selenium WebDriver

On my HTML5 webpage, there are 4 charts that each take a different amount of time to load after the static content has already loaded. The loading process is indicated by a 'rendering' circle image for all 4 charts. I am looking for a way to dete ...