Search code examples
htmlcssflexboxvuetify.jscolumn-count

Using column-count causes flex div to split the element in half


When using column-count with nested divs that have display: flex set I end up with elements that get cut in half. According to this answer I should use display: inline-block to prevent this from happening. However, when I do that I end up with multiple rows on the same line.

In the fiddle below you can press run and see the issue both with and without display: inline-block and the issues with each, along with a description of the issue. (You may need to press "full page" in the top right to really see the issue.) Additionally I have created a pen for easier editing.

new Vue({
  el: '#app',
  vuetify: new Vuetify(),
  data () {
    return {
      checkboxes: [],
      displayInlineBlock: false,
    }
  },
  methods: {
    toggleDisplayInlineBlock() {
      this.displayInlineBlock = !this.displayInlineBlock;
    },
  },
})
.modal {
  width: 750px;
  height: 400px;
  overflow-y: scroll;
  border: 2px solid lightgrey;
}

.container {
  column-count: 3;
}

.v-input--checkbox {
  margin: 0.33em 0;
  padding: 0;
}

.container-inline > div {
  display: inline-block;
}

.btn {
  background-color: tomato;
  color: white;
  padding: 1em;
}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.js"></script><link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@mdi/[email protected]/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css" rel="stylesheet">

<div id="app">
  <v-app>
    <p>(Open snippet in larger window to see issues.)</p>
    <button @click="toggleDisplayInlineBlock" class="btn">
      Toggle Display - currently inline block: {{displayInlineBlock}}
    </button>
    
        <div v-if="displayInlineBlock">
      Current display <b>is</b> set to <code>inline-block</code> which fixes the issue of text being cut off, however, when two elements have short labels they end up on the same line like the "testing" and "abc" checkboxes above. "abc" should be on the line below "testing"
    </div>
    <div v-else>
      Current display is <b>not</b> set to <code>inline-block</code> and the rows end up cut off. For example if you hover over some of the checkboxes you will see that they end up highlighting a checkbox in the next column. Additionally, long text should wrap on the <b>same</b> column
    </div>
    
    <div class="modal">
      <div class="container" :class="{'container-inline': displayInlineBlock}">
        <v-checkbox label="testing"></v-checkbox>
        <v-checkbox label="abc"></v-checkbox>
        <v-checkbox label="testing lorem ipsum"></v-checkbox>
        <v-checkbox label="testing lorem"></v-checkbox>
        <v-checkbox label="testing ip"></v-checkbox>
        <v-checkbox label="testing dorset illemet lorem"></v-checkbox>
        <v-checkbox label="testing super long label text here this is long"></v-checkbox>
      </div>
    </div>
  </v-app>
</div>


Solution

  • The posted code snippet was very close. The only change I made was this:

    .container > div {
      display: inline-block;
      width: 100%;
    }
    

    First you need to set the child elements to inline-block like the answer you already looked at, however you also need to provide the children with a width. By setting the width: 100% your problem goes away.

    new Vue({
      el: '#app',
      vuetify: new Vuetify(),
      data () {
        return {
          checkboxes: [],
        }
      },
    })
    .modal {
      width: 750px;
      height: 400px;
      overflow-y: scroll;
      border: 2px solid lightgrey;
    }
    
    .container {
      column-count: 3;
    }
    
    .v-input--checkbox {
      margin: 0.33em 0;
      padding: 0;
    }
    
    .container > div {
      display: inline-block;
      width: 100%;
    }
    
    .btn {
      background-color: tomato;
      color: white;
      padding: 1em;
    }
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.js"></script><link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
    <link href="https://cdn.jsdelivr.net/npm/@mdi/[email protected]/css/materialdesignicons.min.css" rel="stylesheet">
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css" rel="stylesheet">
    
    <div id="app">
      <v-app>    
        <div class="modal">
          <div class="container">
            <v-checkbox label="testing"></v-checkbox>
            <v-checkbox label="abc"></v-checkbox>
            <v-checkbox label="testing lorem ipsum"></v-checkbox>
            <v-checkbox label="testing lorem"></v-checkbox>
            <v-checkbox label="testing ip"></v-checkbox>
            <v-checkbox label="testing dorset illemet lorem"></v-checkbox>
            <v-checkbox label="testing super long label text here this is long"></v-checkbox>
          </div>
        </div>
      </v-app>
    </div>