QCard component

Cards are usually composed by a header, body and footer part. They might include images in their upper - and call to actions in their lower part. Cards go well together with flexbox or grid layout.

Requirements

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

Usage

Import the following component/s:

import QCard from '../../components/Layout/Cards/QCard.vue'

Cards can be extended using a footer to place call to actions or submit buttons.

A common card element

The card's body can be injected using v-slot:card-body. It can be filled with text, form elements or images. You can also add a footer by adding the v-slot:card-footer.

Example

<q-card title="A common card element" >
  <template v-slot:card-body>
    <p>
      The card's body can be injected using v-slot:card-body.
      It can be filled with text, form elements or images.
      You can also add a footer by adding the v-slot:card-footer.
    </p>
  </template>
  <template v-slot:card-footer>
    <a style="margin-right: 1.5rem;" href="#">Read more</a>
    <a href="#">Sign up</a>
  </template>
</q-card>

Card with an image

an image showing a forest

A card with an image

Images can be bound to the root card element. They will be lazy loaded by default, which can be overwritten by specifying imgLoading="eager"

Example

<q-card
  title="A card with an image"
  imgSrc="../../public/forest.jpg"
  imgAlt="an image showing a forest"
  imgLoading="lazy" >
  <template v-slot:card-body>
    <p>
      Images can be bound to the root card element.
      They will be lazy loaded by default, which can
      be overwritten by specifying imgLoading="eager"
    </p>
  </template>
  <template v-slot:card-footer>
    <div>
      <a style="margin-right: 1.5rem;" href="#">Read more</a>
      <a href="#">Sign up</a>
    </div>
  </template>
</q-card>

Full component's code

QCard

<template>
  <div class="q-card">
    <img class="q-card-image" v-if="imgSrc" :src="imgSrc" :alt="imgAlt" :loading="imgLoading" />
    <div class="q-card-header">
      <h3>{{ title }}</h3>
    </div>
    <div class="q-card-body">
      <slot name="card-body" />
    </div>
    <div class="q-card-footer">
      <slot name="card-footer" />
    </div>
  </div>
</template>


<script>
export default {
  props: {
    imgSrc: {
      type: String,
      required: false,
      default: "",
    },
    imgAlt: {
      type: String,
      required: false,
      default: "",
    },
    imgLoading: {
      type: String,
      required: false,
      default: "lazy",
      validator(value) {
        return ["eager", "lazy"].indexOf(value) !== -1;
      },
    },
    title: {
      type: String,
      required: false,
      default: "A card title",
    },
  },
};
</script>

<style scoped>
.q-card {
  margin: var(--gap-md);
  background-color: var(--background-color-tartiary);
  border-top: 3px solid var(--accent-color-primary);
  border-radius: var(--gap-xs);
  transition: var(--duration-quick) all;
  box-shadow: rgba(0, 0, 0, 0.24) 0px 2px 6px;
}

.q-card-image {
  width: 100%;
  height: auto;
}

.q-card-header {
  margin: var(--gap-xl);
}

.q-card-body {
  margin: var(--gap-md) var(--gap-xl);
}
.q-card-footer {
  padding: var(--gap-md) var(--gap-xl) var(--gap-xl);
}
</style>