Home > Back-end >  Center alignment using flex-box without empty spaces
Center alignment using flex-box without empty spaces

Time:01-25

Hi everyone, i'm currently working on a note project, i'm trying to center my notes using flex box without any useless spaces, take a look at the photos you will understand what i mean .

enter image description here

bottom space is just fine, the problem is the space that is caused by flex box on the right side , i want the yellow box to resize and fit but stay centered as well, the yellow box is a ul tag and the red boxes are li tags.

here is the css styles : ( container includes the whole page except the header )

.container {
  width: 100%;
  display: flex;
  height: 100vh;
  align-items: flex-start;
  justify-content: center;
  position: relative;
}

ul {
  align-content: flex-start;
  margin: 40px auto;
  max-width: 1400px;
  width: fit-content;
  height: 80vh;
  display: flex;
  justify-content: flex-start;
  align-items: flex-start;
  flex-wrap: wrap;
  overflow-y: scroll;
  margin-top: 100px;
  border: 3px solid yellow;
}

ul li {
  border: 2px solid red;
  list-style-type: none;
  font-size: 20px;
  margin: 5px;
  background: linear-gradient(rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5));
  backdrop-filter: blur(10px);
  width: 330px;
  height: 200px;
  display: flex;
  overflow: hidden;
  justify-content: space-between;
  align-items: flex-start;
  flex-direction: column;
  padding: 20px;
  border-radius: 5px;
  position: relative;
  transition: height 0.3s;
}

here is the HTML codes : ( sorry it's not clean )

<title>Dashboard</title>

<div >
  <ul>
    <li >
      <div ></div><span > title </span>
      <span > Content </span>
      <span > date </span>

      <div >
        <a href=""><button ><img  src="/icons/invisible.svg" alt="see icon"></button></button></a>
        <a href=""><button ><img  src="/icons/edit.svg" alt="edit icon"></button></button></a>
        <a href=""><button ><img  src="/icons/trash.svg" alt="delete icon"></button></a>
      </div>
    </li>
  </ul>
</div>

<div >
  <img  src="/add.svg" alt="add new note" />
  <div >
    <a href="/modify/folders">
      <button ><img src="/icons/folder.svg" alt="folder icon"></button>
    </a>
    <a href="/note/add">
      <button ><img src="/icons/pen.svg" alt="pen icon"></button>
    </a>
  </div>
  </div>

CodePudding user response:

As I said in the comment, I don't think you can solve this using pure HTML/CSS, but you could calculate how many elements can fit at given time inside your .container and change width of your ul.

Check this code below:

function totalWidth(element) {
  style = window.getComputedStyle(element)
  return parseFloat(style.marginLeft)   parseFloat(style.marginLeft)   parseFloat(style.width)
}

function resizeContainer() {
  const container = document.querySelector(".container")
  const element = document.querySelector(".container ul")
  const children = document.querySelector(".container ul li")
  const childrenWidth = totalWidth(children)
  const amountFits = Math.floor(Math.min(container.offsetWidth, 1400) / childrenWidth)
  element.style.width = `${childrenWidth * amountFits}px`
}

resizeContainer()
window.addEventListener("resize", resizeContainer)
.container {
  width: 100%;
  display: flex;
  height: 100vh;
  align-items: flex-start;
  justify-content: center;
  position: relative;
}

ul {
  align-content: flex-start;
  margin: 40px auto;
  max-width: 1400px;
  width: fit-content;
  height: 80vh;
  display: flex;
  justify-content: flex-start;
  align-items: flex-start;
  flex-wrap: wrap;
  overflow-y: scroll;
  margin-top: 100px;
  border: 3px solid yellow;
  padding: 0;
}

ul li {
  border: 2px solid red;
  list-style-type: none;
  font-size: 20px;
  margin: 5px;
  background: linear-gradient(rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5));
  backdrop-filter: blur(10px);
  width: 330px;
  height: 200px;
  display: flex;
  overflow: hidden;
  justify-content: space-between;
  align-items: flex-start;
  flex-direction: column;
  padding: 20px;
  border-radius: 5px;
  position: relative;
  transition: height 0.3s;
  box-sizing: border-box;
}
<div >
<ul>
<li>test</li><li>test</li>
<li>test</li><li>test</li>
</ul>
</div>

Mind the fact that I added box-sizing: border-box; to your ul li so it's a bit easier to calculate the actual size of the element. Naturally you could ignore this and change my totalWidth method to calculate it the way you'd like.

I don't think you can do it differently but I'd like to be proven wrong.

CodePudding user response:

There's a number of solutions for this one, depending which way you want to go,

If the notes don't have to be exactly 330px wide, you can achieve removing the gaps by replacing:

width: 330px;

with

flex: 200px;

This takes advantage of the fluid responsiveness of flexbox.

One issue with this flex solution is the 'leftover' element upon wrapping: e.g. with three elements across, the fourth will wrap and grow to the full width of the parent:

CSS flex-grow causing the last element to stretch out

To get around this with flex, you would need to either:

  1. change flex to something like flex: 0 1 50%; with percentage values and flex-grow disabled, which means you would need @media queries to give the lists the fluidity they had before
  2. use a JavaScript solution to dynamically set the width of the last element based on the other lists (like @SnoopFrog's answer)

If you do need the notes to be 330px wide, I would set the parent <ul> to have a set size twice that of the lists width: 785px; and ensure that justify-content: center;


Alternatively, turning to CSS grid or a simple inline-block method may fit your needs but both would need @media queries for responsivity.

CodePudding user response:

* {
    /* just for reset and for remove all margins and paddings */
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

ul {
    display: flex;
    /*justify-content: flex-start; don't need this, is start by default
    align-items: flex-start;*/
    /* magical words that they can align internal box(li) */
    justify-content: center;  
    align-items: center;

    margin: 40px auto; /*auto <--> both part is ok*/
    max-width: 1400px;
    /* just for see the center(you can remove this width static of 25rem */
    width: 25rem; /* width: fit-content; */
    height: 80vh;
    overflow-y: scroll;
    margin-top: 100px;
    border: 3px solid yellow;
}

ul li {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    flex-direction: column;

    border: 2px solid red;
    list-style-type: none;
    background: linear-gradient(rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5));
    backdrop-filter: blur(10px);
    width: min(100%, 330px);   /*make it responsive, when shrink down, under 330px, is take 100% of width avaiable, and not overflowing*/
    height: 200px;
    margin: 10px auto; /*in every elements, you can use margin auto for both parts*/
    padding: 20px;
    border-radius: 5px;
    transition: all 0.3s; /*transition:height 0.3  --> not height, but all inside!*/
    /* overflow: hidden; don't need, that not should be overflow */
    /* position: relative; Is by default! like height:auto*/
}

/* if you want to style your buttons, write this code all times */
/* remove deafult aspect of a btn and others, beacuse every browser take a different style*/
button, input, a {
    appearance: none;
        -webkit-appearance: none;
            -moz-appearance: none;
}
<title>Dashboard</title>


    <ul>
        <div >
            <li >
                <div ></div>
                <span > title </span>
                <span > Content </span>
                <span > date </span>

                <div >
                    <a href="">
                        <button >
                            <img  src="/icons/invisible.svg" alt="see icon">
                        </button>
                    </a>
                    <a href="">
                        <button >
                            <img  src="/icons/edit.svg" alt="edit icon">
                        </button>
                    </a>
                    <a href="">
                        <button >
                            <img  src="/icons/trash.svg" alt="delete icon">
                        </button>
                    </a>
                </div>
            </li>
        </div>
    </ul>


    <div >
        <img  src="/add.svg" alt="add new note" />
        <div >
            <a href="/modify/folders">
                <button >
                    <img src="/icons/folder.svg" alt="folder icon">
                </button>
            </a>
            <a href="/note/add">
                <button >
                    <img src="/icons/pen.svg" alt="pen icon">
                </button>
            </a>
        </div>
    </div>

  • Related