QFlex components

Whenever the layouts QGrid provides are not sufficient, QFlex provides a more customizable approach. It extends the maximum count of columns from 4 to 12 and includes a powerful & responsive column component.

Requirements

TypePath / VersionPurposeOptional
Styles../../assets/main.cssCSS VariablesNo

Usage

Import the following component/s:

import QFlexContainer from '../../components/Layout/Flex/QFlexContainer.vue'
import QFlexColumn from '../../components/Layout/Flex/QFlexColumn.vue'

Basic usage

Flex columns scale automatically depending on how many elements are nested within its parent component. That means that if no column attribute is bound, columns will take up all the remaining space within.

Column 1 / 3
Column 2 / 3
Column 3 / 3
Column 1 / 6
Column 2 / 6
Column 3 / 6
Column 4 / 6
Column 5 / 6
Column 6 / 6

Example

<q-flex-container>
  <q-flex-column>Column 1 / 3</q-flex-column>
  <q-flex-column>Column 2 / 3</q-flex-column>
  <q-flex-column>Column 3 / 3</q-flex-column>
</q-flex-container>

<q-flex-container>
  <q-flex-column>Column 1 / 6</q-flex-column>
  <q-flex-column>Column 2 / 6</q-flex-column>
  <q-flex-column>Column 3 / 6</q-flex-column>
  <q-flex-column>Column 4 / 6</q-flex-column>
  <q-flex-column>Column 5 / 6</q-flex-column>
  <q-flex-column>Column 6 / 6</q-flex-column>
</q-flex-container>

Set columns manually

If you're familiar with bootstrap's grid system, this one will be a breeze. The maximum amount of columns that can be assigned are 12

3 / 12 columns
5 / 12 columns
4 / 12 columns

Example

<q-flex-container>
  <q-flex-column :cols="3">3 / 12 columns </q-flex-column>
  <q-flex-column :cols="5">5 / 12 columns</q-flex-column>
  <q-flex-column :cols="4">4 / 12 columns</q-flex-column>
</q-flex-container>

Fluid sizing

Unline QGrid, QFLex does not scale down with screensize. Therefor, setting this container to fluid grants only a bit of additional spacing

3 / 12 columns
5 / 12 columns
4 / 12 columns

Example

<q-flex-container :fluid="true">
  <q-flex-column :cols="3">3 / 12 columns </q-flex-column>
  <q-flex-column :cols="5">5 / 12 columns</q-flex-column>
  <q-flex-column :cols="4">4 / 12 columns</q-flex-column>
</q-flex-container>

Responsive column sizing

Just like with the grid sizing, QFlex follows the standard layout media queries. For each screen size, a column width can be specified:

Vue AttributeMedia Query
smCols(max-width: 768px)
mdCols(max-width: 992px) and (min-width: 768px)
lgCols(max-width: 1200px) and (min-width: 992px)
xlCols(min-width: 1200px)
The width of the inner column scales up with screen size

Example

<q-flex-container>
  <q-flex-column></q-flex-column>
  <q-flex-column :smCols="12" :mdCols="10" :lgCols="8" :xlCols="6">
    Inner column's width scales up with screen size
  </q-flex-column>
  <q-flex-column></q-flex-column>
</q-flex-container>

Full component's code

QFlexContainer

<template>
  <div
    class="q-flex"
    :class="{
      'q-flex-fluid': fluid === true,
      'q-flex-full-page': onepager === true,
    }"
  >
    <slot />
  </div>
</template>

<script>
export default {
  props: {
    fluid: {
      type: Boolean,
      required: false,
      default: false,
    },
    onepager: {
      type: Boolean,
      required: false,
      default: false,
    },
  },
};
</script>

<style scoped>
.q-flex {
  margin: auto;
  width: 95%;
  display: flex;
  flex-wrap: wrap;
}

.q-flex-fluid {
  width: 100%;
}

.q-flex-full-page {
  height: 100vh;
  align-items: center;
  justify-content: center;
}
</style>

QFlexColumn

<template>
  <div
    :class="{
      'q-flex-col': hasSizedColumns,
      'q-flex-col-auto': hasNoColumns,

      'q-flex-col-1': cols === 1,
      'q-flex-col-2': cols === 2,
      'q-flex-col-3': cols === 3,
      'q-flex-col-4': cols === 4,
      'q-flex-col-5': cols === 5,
      'q-flex-col-6': cols === 6,
      'q-flex-col-7': cols === 7,
      'q-flex-col-8': cols === 8,
      'q-flex-col-9': cols === 9,
      'q-flex-col-10': cols === 10,
      'q-flex-col-11': cols === 11,
      'q-flex-col-12': cols === 12,

      'q-flex-col-sm-1': smCols === 1,
      'q-flex-col-sm-2': smCols === 2,
      'q-flex-col-sm-3': smCols === 3,
      'q-flex-col-sm-4': smCols === 4,
      'q-flex-col-sm-5': smCols === 5,
      'q-flex-col-sm-6': smCols === 6,
      'q-flex-col-sm-7': smCols === 7,
      'q-flex-col-sm-8': smCols === 8,
      'q-flex-col-sm-9': smCols === 9,
      'q-flex-col-sm-10': smCols === 10,
      'q-flex-col-sm-11': smCols === 11,
      'q-flex-col-sm-12': smCols === 12,

      'q-flex-col-md-1': mdCols === 1,
      'q-flex-col-md-2': mdCols === 2,
      'q-flex-col-md-3': mdCols === 3,
      'q-flex-col-md-4': mdCols === 4,
      'q-flex-col-md-5': mdCols === 5,
      'q-flex-col-md-6': mdCols === 6,
      'q-flex-col-md-7': mdCols === 7,
      'q-flex-col-md-8': mdCols === 8,
      'q-flex-col-md-9': mdCols === 9,
      'q-flex-col-md-10': mdCols === 10,
      'q-flex-col-md-11': mdCols === 11,
      'q-flex-col-md-12': mdCols === 12,

      'q-flex-col-lg-1': lgCols === 1,
      'q-flex-col-lg-2': lgCols === 2,
      'q-flex-col-lg-3': lgCols === 3,
      'q-flex-col-lg-4': lgCols === 4,
      'q-flex-col-lg-5': lgCols === 5,
      'q-flex-col-lg-6': lgCols === 6,
      'q-flex-col-lg-7': lgCols === 7,
      'q-flex-col-lg-8': lgCols === 8,
      'q-flex-col-lg-9': lgCols === 9,
      'q-flex-col-lg-10': lgCols === 10,
      'q-flex-col-lg-11': lgCols === 11,
      'q-flex-col-lg-12': lgCols === 12,

      'q-flex-col-xl-1': xlCols === 1,
      'q-flex-col-xl-2': xlCols === 2,
      'q-flex-col-xl-3': xlCols === 3,
      'q-flex-col-xl-4': xlCols === 4,
      'q-flex-col-xl-5': xlCols === 5,
      'q-flex-col-xl-6': xlCols === 6,
      'q-flex-col-xl-7': xlCols === 7,
      'q-flex-col-xl-8': xlCols === 8,
      'q-flex-col-xl-9': xlCols === 9,
      'q-flex-col-xl-10': xlCols === 10,
      'q-flex-col-xl-11': xlCols === 11,
      'q-flex-col-xl-12': xlCols === 12,
    }"
  >
    <slot />
  </div>
</template>

<script>
export default {
  computed: {
    // Used to determine whether to apply auto sizing
    hasNoColumns() {
      return (
        !this.cols &&
        !this.smCols &&
        !this.mdCols &&
        !this.lgCols &&
        !this.xlCols
      );
    },

    // Used to determine whether to apply padding
    hasSizedColumns() {
      return (
        (this.cols && this.cols > 0) ||
        (this.smCols && this.smCols > 0) ||
        (this.mdCols && this.mdCols > 0) ||
        (this.lgCols && this.lgCols > 0) ||
        (this.xlCols && this.xlCols > 0)
      );
    },
  },
  props: {
    cols: {
      type: Number,
      required: false,
      default: undefined,
      validator(value) {
        return (value >= 0 && value <= 12) || undefined;
      },
    },

    smCols: {
      type: Number,
      required: false,
      default: undefined,
      validator(value) {
        return (value >= 0 && value <= 12) || undefined;
      },
    },

    mdCols: {
      type: Number,
      required: false,
      default: undefined,
      validator(value) {
        return (value >= 0 && value <= 12) || undefined;
      },
    },

    lgCols: {
      type: Number,
      required: false,
      default: undefined,
      validator(value) {
        return (value >= 0 && value <= 12) || undefined;
      },
    },

    xlCols: {
      type: Number,
      required: false,
      default: undefined,
      validator(value) {
        return (value >= 0 && value <= 12) || undefined;
      },
    },
  },
};
</script>

<style scoped>
/* Column styles were strongly influenced by bootstrap CSS */
.q-flex-col {
  padding-left: var(--gap-xl);
  padding-right: var(--gap-xl);
}

.q-flex-col-auto {
  flex: 1 0 0%;
}

.q-flex-col-1 {
  width: 8.33333%;
}
.q-flex-col-2 {
  width: 16.66667%;
}
.q-flex-col-3 {
  width: 25%;
}
.q-flex-col-4 {
  width: 33.33333%;
}
.q-flex-col-5 {
  width: 41.66667%;
}
.q-flex-col-6 {
  width: 50%;
}
.q-flex-col-7 {
  width: 58.33333%;
}
.q-flex-col-8 {
  width: 66.66667%;
}
.q-flex-col-9 {
  width: 75%;
}
.q-flex-col-10 {
  width: 83.33333%;
}
.q-flex-col-11 {
  width: 91.66667%;
}
.q-flex-col-12 {
  width: 100%;
}

/* sm */
@media (max-width: 768px) {
  .q-flex-col-sm-1 {
    width: 8.33%;
  }
  .q-flex-col-sm-2 {
    width: 16.67%;
  }
  .q-flex-col-sm-3 {
    width: 25%;
  }
  .q-flex-col-sm-4 {
    width: 33.33%;
  }
  .q-flex-col-sm-5 {
    width: 41.67%;
  }
  .q-flex-col-sm-6 {
    width: 50%;
  }
  .q-flex-col-sm-7 {
    width: 58.33%;
  }
  .q-flex-col-sm-8 {
    width: 66.66%;
  }
  .q-flex-col-sm-9 {
    width: 75%;
  }
  .q-flex-col-sm-10 {
    width: 83.33%;
  }
  .q-flex-col-sm-11 {
    width: 91.67%;
  }
  .q-flex-col-sm-12 {
    width: 100%;
  }
}

/* md */
@media (max-width: 992px) and (min-width: 768px) {
  .q-flex-col-md-1 {
    width: 8.33%;
  }
  .q-flex-col-md-2 {
    width: 16.67%;
  }
  .q-flex-col-md-3 {
    width: 25%;
  }
  .q-flex-col-md-4 {
    width: 33.33%;
  }
  .q-flex-col-md-5 {
    width: 41.67%;
  }
  .q-flex-col-md-6 {
    width: 50%;
  }
  .q-flex-col-md-7 {
    width: 58.33%;
  }
  .q-flex-col-md-8 {
    width: 66.66%;
  }
  .q-flex-col-md-9 {
    width: 75%;
  }
  .q-flex-col-md-10 {
    width: 83.33%;
  }
  .q-flex-col-md-11 {
    width: 91.67%;
  }
  .q-flex-col-md-12 {
    width: 100%;
  }
}

/* lg */
@media (max-width: 1200px) and (min-width: 992px) {
  .q-flex-col-lg-1 {
    width: 8.33%;
  }
  .q-flex-col-lg-2 {
    width: 16.67%;
  }
  .q-flex-col-lg-3 {
    width: 25%;
  }
  .q-flex-col-lg-4 {
    width: 33.33%;
  }
  .q-flex-col-lg-5 {
    width: 41.67%;
  }
  .q-flex-col-lg-6 {
    width: 50%;
  }
  .q-flex-col-lg-7 {
    width: 58.33%;
  }
  .q-flex-col-lg-8 {
    width: 66.66%;
  }
  .q-flex-col-lg-9 {
    width: 75%;
  }
  .q-flex-col-lg-10 {
    width: 83.33%;
  }
  .q-flex-col-lg-11 {
    width: 91.67%;
  }
  .q-flex-col-lg-12 {
    width: 100%;
  }
}

/* xl */
@media (min-width: 1200px) {
  .q-flex-col-xl-1 {
    width: 8.33%;
  }
  .q-flex-col-xl-2 {
    width: 16.67%;
  }
  .q-flex-col-xl-3 {
    width: 25%;
  }
  .q-flex-col-xl-4 {
    width: 33.33%;
  }
  .q-flex-col-xl-5 {
    width: 41.67%;
  }
  .q-flex-col-xl-6 {
    width: 50%;
  }
  .q-flex-col-xl-7 {
    width: 58.33%;
  }
  .q-flex-col-xl-8 {
    width: 66.66%;
  }
  .q-flex-col-xl-9 {
    width: 75%;
  }
  .q-flex-col-xl-10 {
    width: 83.33%;
  }
  .q-flex-col-xl-11 {
    width: 91.67%;
  }
  .q-flex-col-xl-12 {
    width: 100%;
  }
}
</style>