0

The following example I want column to be equal width and spacing. But I don't want to use width, min-width, max-width property for any columns.

Anyone help me to achieve this by using flex or any other method.

img

.d-flex {
    display: flex;
}
.d-flex .col {
    margin: 5px;
    background: #7adaff;
}
<div class="d-flex">
    <div class="col">
        Lorem Ipsum is simply dummy text of the printing and typesetting industry
    </div>
    <div class="col">
        Lorem Ipsum is simply dummy tex
    </div>
    <div class="col">
        Lorem Ipsum
    </div>
    <div class="col">
        Lorem Ipsum
    </div>
    <div class="col">
        Lorem Ipsum is simply dummy text of the printing and typesetting industryLorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type
        specimen book. It has survived not only five centuries,
    </div>
</div>

If you have any questions kindly drop your comment.

Saravana
  • 3,389
  • 4
  • 21
  • 37

2 Answers2

2

There are a couple of possibilities, one of which uses CSS flex-box layout, and the other using CSS Grid; neither using an explicit width, min-width, or max-width but the flex solution does use flex-basis, but this feels like exploiting a loophole or technicality:

.d-flex {
  display: flex;
  /* using gap allows the spacing to be set on
     the parent: */
  gap: 5px;
}

.d-flex .col {
  /* here we use calc to work out the flex-basis value,
     100% is the width of the parent element,
     from which we subtract the number of gaps multiplied
     by the gap-size, and divide the result of that by
     the number of children: */
  flex-basis: calc((100% - (4*5px))/5);
  background: #7adaff;
}
<div class="d-flex">
  <div class="col">
    Lorem Ipsum is simply dummy text of the printing and typesetting industry
  </div>
  <div class="col">
    Lorem Ipsum is simply dummy tex
  </div>
  <div class="col">
    Lorem Ipsum
  </div>
  <div class="col">
    Lorem Ipsum
  </div>
  <div class="col">
    Lorem Ipsum is simply dummy text of the printing and typesetting industryLorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has
    survived not only five centuries,
  </div>
</div>

More sensibly, we can use CSS Grid, and exploit the fr fractional units:

.d-flex {
  display: grid;
  /* defining five columns (number of children), each
     of which is 1fr (fraction of the available space): */
  grid-template-columns: repeat(5, 1fr);
  gap: 5px;
}

.d-flex .col {
  background: #7adaff;
}
<div class="d-flex">
  <div class="col">
    Lorem Ipsum is simply dummy text of the printing and typesetting industry
  </div>
  <div class="col">
    Lorem Ipsum is simply dummy tex
  </div>
  <div class="col">
    Lorem Ipsum
  </div>
  <div class="col">
    Lorem Ipsum
  </div>
  <div class="col">
    Lorem Ipsum is simply dummy text of the printing and typesetting industryLorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has
    survived not only five centuries,
  </div>
</div>

Following OP's comment (below):

What should I do when [I] use dynamic column counts[?]

My only suggestion is to use JavaScript, though how that JavaScript should work depends on the precise circumstances and – potentially – exceeds the scope of the original question. However, the following is certainly possible:

// some utitlities that I'm using to reduce typing, and for convenience:
const D = document,
  create = (tag, props) => Object.assign(D.createElement(tag), props),
  get = (selector, context = D) => context.querySelector(selector),
  // the sample text from which the text-snippets will be added:
  sampleText = [
    "Lorem", "ipsum", "dolor", "sit", "amet,", "consectetur", "adipisicing", "elit.", "Quas", "a", "repellendus", "sit", "libero", "odio", "aut", "eos", "nihil", "nisi", "quisquam", "aspernatur", "ad", "enim,", "possimus", "amet", "expedita", "facilis,", "architecto", "adipisci", "nulla", "eligendi", "incidunt", "iusto", "pariatur", "laudantium,", "qui", "quaerat", "voluptatem", "inventore.", "Nulla", "suscipit", "cumque", "repudiandae,", "eveniet", "reprehenderit", "quidem", "repellat", "necessitatibus", "consequuntur", "dolore", "id", "modi", "laboriosam", "pariatur", "ex", "delectus!", "Nesciunt", "consequatur", "ducimus", "eveniet", "amet!"
  ],
  // the length of the array of words:
  sampleWordCount = sampleText.length,
  // the function for adding new elements/content:
  addContent = () => {
    // caching the element to which content should be added:
    let parent = get('.d-flex'),
            // taking a number of words from the array of words to create the text:
          text = sampleText.slice(0, Math.floor(Math.random() * sampleWordCount)).join(' '),
            // here we use the create() function to create a <div> element:
        div = create('div', {
            // with the following properties, setting the element's className to 'col':
          className: 'col',
          // setting the textContent to the text we retrieved:
          textContent: text,
        });
    // we append the <div> to the parent .d-flex element:
    parent.append(div);
    // we set the value of the '--childCount' custom property on the parent,
    // to reflect the number of child elements:
    parent.style.setProperty('--childCount', parent.children.length);
  },
  // we retrieve the '<button> element:'
  button = get('button');
// and bind the addContents() function as the event-handler for
// the 'click' event:
button.addEventListener('click', addContent);
.d-flex {
  display: grid;
  grid-template-columns: repeat(var(--childCount), 1fr);
  gap: 5px;
}

.d-flex .col {
  background: #7adaff;
}
<button type="button" id="add">Add content</button>
<!-- the following element has a CSS custom property defined in the style
     attribute; this could be populated by the server on the back-end, or
     via JavaScript on the front-end: -->
<div class="d-flex" style="--childCount: 2;">
  <div class="col">
    Lorem Ipsum is simply dummy text of the printing and typesetting industry
  </div>
  <div class="col">
    Lorem Ipsum is simply dummy text
  </div>
</div>

JS Fiddle demo.

References:

Bibliography:

David Thomas
  • 249,100
  • 51
  • 377
  • 410
  • for dynamic column how can I use `grid-template-columns`, `flex-basis` – Saravana Nov 09 '22 at 12:26
  • I can't tell what you're asking exactly; but `grid-template-columns` is only applicable to grid layouts and `flex-basis` is only applicable to flex layouts. Using them both in the same layout may not be impossible, but I'd be surprised. Incidentally, if you're able to watch Kevin's video then please do: it explains succinctly and clearly why - for this type of layout - grid is probably the better choice. – David Thomas Nov 09 '22 at 12:33
  • I want to use either `grid-template-columns` or `flex-basis` not at the same time. column width count will be differ like 5,3,2 – Saravana Nov 09 '22 at 12:45
  • Okay, but that's what I'm doing in my answer; how is not working or breaking for you? – David Thomas Nov 09 '22 at 12:47
  • for this solution column width will be set to 5. What should I do when use dynamic column counts. – Saravana Nov 09 '22 at 12:49
  • In that case I believe you'd need to use JavaScript (or a backend solution) to set a property to represent the number of children. – David Thomas Nov 09 '22 at 12:54
  • Okay. Let me try this. – Saravana Nov 09 '22 at 13:00
  • @Saravana for the last one you can use `grid-auto-flow: column; grid-auto-columns: 1fr` and you don't JS. – Temani Afif Nov 09 '22 at 14:58
0

In this instance I would prefer to set the flex shorthand value per child of the flexbox parent container. Combined with a custom attribute ([col]) instead of a class (.col) it will become very easy to vary between column widths if so required (comparable to using grid fractions).

Further explanations can be found in the CSS of the snippet

/* Include border width in total element width */
* { box-sizing: border-box }

/********************/
/* GENERIC behavior */
/********************/
.d-flex   { display: flex }

[col]     { flex: 1 } /* 1x, by default assume all columns are equal */
[col="2"] { flex: 2 } /* x2, overrides assigned space as required */
[col="3"] { flex: 3 } /* x3 */
[col="4"] { flex: 4 } /* x4 */

/*
    'flex' is a shorthand for: 
        'flex-grow'   - 0 (default, no grow)
        'flex-shrink' - 1
        'flex-basis'  - 0%

    so 'flex: 1' will default to 'flex: 1 1 0%'
*/

/*********************************/
/* [OPTIONAL] For responsiveness */
/*********************************/
.d-flex { flex-wrap: wrap } /* default is 'nowrap' */

[col] {
    min-width: min(6rem, 100%); /* Flexbox will wrap at this value */
    /* viewport width dependend, whichever value comes first */
}

/***************************/
/* DEMO specific eye-candy */
/***************************/
.d-flex {
    gap: 5px; /* no need for margins */
}

.d-flex [col] {
    background: #7adaff;
    padding: 0.5rem; /* some inner space */

    word-break: break-word; /* break long words that don't fit  */
    -webkit-hyphens: auto;  /* and place a hypen where required */
        -ms-hyphens: auto;  /* poor support, requires vendor prefixes */
            hyphens: auto;
}
<div class="d-flex">
    <div col>
        Lorem Ipsum is simply dummy text of the printing and typesetting industry
    </div>
    <div col>
        Lorem Ipsum is simply dummy tex
    </div>
    <div col>
        Lorem Ipsum
    </div>
    <div col>
        Lorem Ipsum
    </div>
    <div col="2"><b>(demo: with 'flex: 2')</b>
        Lorem Ipsum is simply dummy text of the printing and typesetting industryLorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type
        specimen book. It has survived not only five centuries.
    </div>
</div>
Rene van der Lende
  • 4,992
  • 2
  • 14
  • 25