Home > Software design >  CSS problem in creating a flexible list in two columns
CSS problem in creating a flexible list in two columns

Time:06-13

I want to use flex property to have a list in two columns and become one column when the content of each item is out of the display.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <style>
      .flexcontainer {
        display: flex;
        flex-wrap: wrap;
      }
      .leftflex,
      .rightflex {
        box-sizing: border-box;
        flex: 50%;
      }
      body {font-size: 30px;}
    </style>
  </head>
  <body>
    <ul >
      <span >
        <li>1 Lorem, ipsum.</li>
        <li>2 Lorem, ipsum.</li>
      </span>
      <span >
        <li>3 Lorem, ipsum.</li>
        <li>4 Lorem, ipsum.</li>
      </span>
    </ul>
  </body>
</html>


but there are two problems here:

  1. When I make the screen size smaller, each item becomes two lines but I want to have a single column before this happens.
    I want this:

    but I've got this:

    If I set white-space: nowrap; for the list, the text won't wrap even in single column and it a is problem for long items:

    I know I can use @media (max-width: #px) but I want to change flex and wrap properties based on content not screen size only.
  2. Apparently flex does not consider bullet of list in fitting contents and I don't know how to fix this
    (I tried to use calc function to set flex: calc(50%-10px) but didn't work.) :

CodePudding user response:

  1. The problem is with flex-basis. If you remove flex: 50% (which basically means flex-grow: 1 and flex-basis: 50%), you will essentially set flex-basis back to auto, and get the 1 column before the text begins wrapping. (might want to keep flex-grow so the whole container stills takes up a whole row).
  2. As for the bullets, you can specify list-style-position: inside, that will get rid of that weird overlap thing.

Your code will look like this:

.flexcontainer {
    display: flex;
    flex-wrap: wrap;
    list-style-position: inside;
}
.leftflex,
.rightflex {
    box-sizing: border-box;
    flex-grow: 1;
}

CodePudding user response:

You can use with a grid

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <style>
      .flexcontainer {
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(240px, 1fr) ) ;
      }
      .leftflex,
      .rightflex {
        box-sizing: border-box;
        flex: 50%;
      }
      body {font-size: 30px;}
    </style>
  </head>
  <body>
    <ul >
      <span >
        <li>1 Lorem, ipsum.</li>
        <li>2 Lorem, ipsum.</li>
      </span>
      <span >
        <li>3 Lorem, ipsum.</li>
        <li>4 Lorem, ipsum.</li>
      </span>
    </ul>
  </body>
</html>

CodePudding user response:

You can use flex-basis to define a width where you want it to start wrapping. To prevent the bullets overlapping when there is more text in the list you can add some padding to compensate.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <style>
      .flexcontainer {
        display: flex;
        flex-wrap: wrap;
        margin: 0 -1rem;
      }
      .leftflex,
      .rightflex {
        box-sizing: border-box;
        flex: 50%;
        flex-basis: 250px;
        padding: 0 1rem;
      }
      body {font-size: 30px;}
    </style>
  </head>
  <body>
    <ul >
      <span >
        <li>1 Lorem, ipsum. flex-basis flex-basis flex-basis</li>
        <li>2 Lorem, ipsum. flex-basis flex-basis</li>
      </span>
      <span >
        <li>3 Lorem, ipsum. flex-basis flex-basis</li>
        <li>4 Lorem, ipsum.</li>
      </span>
    </ul>
  </body>
</html>

  • Related