Search code examples
htmlcsscentering

center on the screen specific column in each row css


I'm new to web development and as my first project, I'm designing a visualization of projects I'm working on which I'd like to look like this: enter image description here

I'm having a hard time centering the star in each row. This is the current code looks like this:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Amarante&display=swap">
  <style>
    body {
      background-color: #124264;
      color: #000000;
      font-family: 'Amarante';
      margin: 0;
      /*display: flex;
      align-items: center;
      justify-content: flex-end; /* Adjusted alignment to right */
      height: 100vh;
      overflow: auto;
    }


    /* Style for the first image */
    .starImages {
      width: 90px; /* Set the desired width */
      height: auto; /* Maintain aspect ratio */
      vertical-align: middle; /* Align the star icon with text */
    }

    /* Remove bullet points from the list */
    #projectNamesList {
      list-style: none;
      display: grid; /* Use grid display */
      grid-template-columns: 1fr; /* One column for each item */
      /*align-items: flex-end; /* Align items to the right */
      padding: 0; /* Remove default padding */
      overflow-x: auto; /* Allow horizontal scrolling */
      /*justify-items: flex-end; /* Align items to the right */
      justify-items: center;
    }

  
    /* Style for individual list items */
    .projectItem {
      display: flex;
      align-items: center;
      white-space: nowrap; /* Prevent line breaks within items */
      position: relative; /* Position relative for adding line */
    }

    /* Add a gold line */
    .thinLine {
      position: relative;
      height: 2px;
      background-color: #E0B624;
      margin-left: 0px;

    }

    .thickLine {
      position: relative;
      height: 10px;
      background-color: #E0B624;
      z-index: -1
    }
  </style>
</head>
<body>
  <ul id="projectNamesList"></ul>

  <script>
    async function fetchData() {
      try {
        const response = await fetch('https://us-central1-project-organization-noa.cloudfunctions.net/getData'); // Cloud Function URL
        console.log(response);
        const data = await response.json();
        console.log(data);

        const projectNamesList = document.getElementById('projectNamesList');
        dataWithoutHeader = data.slice(1);
        dataWithoutHeader.forEach(row => {
          const listItem = document.createElement('li');
          listItem.classList.add('projectItem'); // Add the class for styling

          // Create a span for the project name
          const projectNameSpan = document.createElement('span');
          projectNameSpan.textContent = row[0];

          // Create an image element for the star icon
          const starIcon = document.createElement('img');
          starIcon.src = 'star.svg';
          starIcon.alt = 'Star';
          starIcon.classList.add('starImages');

          // Create the gold line element
          const thickLine = document.createElement('div');
          thickLine.classList.add('thickLine');
          daysSince = row[2];
          numericThickWidth = 7 * Math.sqrt(daysSince)
          thickWidth = numericThickWidth + 'px';
          thickLine.style.width = thickWidth;
          percent = row[5] / 100;
          thinWidth = numericThickWidth * ((1 / percent) - 1) + 'px';

          //thinWidth = parseInt();
          const thinLine = document.createElement('div');
          thinLine.classList.add('thinLine');
          thinLine.style.width = thinWidth;

          projectNameSpan.style.marginRight = - numericThickWidth + 'px';

          // Append the elements to the list item
          listItem.appendChild(projectNameSpan);
          listItem.appendChild(thickLine);
          listItem.appendChild(starIcon);
          listItem.appendChild(thinLine);

          projectNamesList.appendChild(listItem);
        });

        // Center scroll
        const halfWidth = projectNamesList.scrollWidth / 2;
        const halfViewport = window.innerWidth / 2;
        projectNamesList.scrollLeft = halfWidth - halfViewport;

      } catch (error) {
        console.error('Error fetching data:', error);
      }
    }

    fetchData();
  </script>
</body>
</html>

Here is what the website looks like now with uncentered stars: enter image description here

Things I've tried:

  • flex boxes
  • searching for other stackoverflow answers (they were all about centering text not elements)
  • using a grid
  • setting ever attribute I could find to 'center'

Thank you for any pointers you can give!


Solution

  • I would use a three-column grid to achieve this layout, with the left column containing the thick line and the title, the centre column containing the star, and the right column containing the thin line.

    The other key to making it work is that grids don’t have row elements with nested cell elements like tables do, they only have child elements. Your grid (a style on the <ul> element) needs its child elements to be the children of your <li> elements, not the <li> elements themselves. Use display: contents on the <li> elements to achieve this.

    #projectNamesList {
      display: grid;
      grid-template-columns: auto 30px auto;
    }
    
    .projectItem {
      display: contents;
    }
    

    A working snippet to demonstrate:

    async function fetchData() {
          try {
            const response = await fetch('https://us-central1-project-organization-noa.cloudfunctions.net/getData'); // Cloud Function URL
            console.log(response);
            const data = await response.json();
            console.log(data);
    
            const projectNamesList = document.getElementById('projectNamesList');
            dataWithoutHeader = data.slice(1);
            dataWithoutHeader.forEach(row => {
              const listItem = document.createElement('li');
              listItem.classList.add('projectItem'); // Add the class for styling
    
              // Create a span for the project name
              const projectNameSpan = document.createElement('span');
              projectNameSpan.textContent = row[0];
    
              // Create an image element for the star icon
              const starIcon = document.createElement('img');
              starIcon.src = 'https://mario.wiki.gallery/images/b/bb/MPS_Favicon.svg';
              starIcon.alt = 'Star';
              starIcon.classList.add('starImages');
    
              // Create the gold line element
              const thickLine = document.createElement('div');
              thickLine.classList.add('thickLine');
              daysSince = row[2];
              numericThickWidth = 7 * Math.sqrt(daysSince)
              thickWidth = numericThickWidth + 'px';
              thickLine.style.width = thickWidth;
              percent = row[5] / 100;
              thinWidth = numericThickWidth * ((1 / percent) - 1) + 'px';
    
              //thinWidth = parseInt();
              const thinLine = document.createElement('div');
              thinLine.classList.add('thinLine');
              thinLine.style.width = thinWidth;
    
              const lineWithTitle = document.createElement('div');
              lineWithTitle.classList.add('lineWithTitle');
    
              // Append the elements to the list item
              lineWithTitle.appendChild(thickLine);
              lineWithTitle.appendChild(projectNameSpan);
              listItem.appendChild(lineWithTitle);
              listItem.appendChild(starIcon);
              listItem.appendChild(thinLine);
    
              projectNamesList.appendChild(listItem);
            });
    
          } catch (error) {
            console.error('Error fetching data:', error);
          }
        }
    
        fetchData();
    body {
      background-color: #124264;
      color: #000000;
      font-family: 'Amarante';
      margin: 0;
      height: 100vh;
      overflow: auto;
    }
    
    .starImages {
      width: 100%;
    }
    
    #projectNamesList {
      list-style: none;
      display: grid;
      grid-template-columns: auto 30px auto;
      align-items: center;
    }
    
    .projectItem {
      display: contents;
    }
    
    .lineWithTitle {
      text-align: right;
      position: relative;
    }
    
    .thickLine {
      height: 10px;
      background-color: #E0B624;
      margin: 0 0 0 auto;
    }
    
    .thickLine+span {
      position: absolute;
      right: 0;
      top: -5px;
    }
    
    .thinLine {
      height: 2px;
      background-color: #E0B624;
    }
    <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Amarante&display=swap">
    
      <ul id="projectNamesList"></ul>