<section class="demo-intro">
  <div class="container">
    <h1>Container queries for CTA's</h1>
    <p>Change styling when amount of call to actions isn't known (resize your window). <a href="https://utilitybend.com/blog/styling-based-on-container-width-made-possible-with-css-container-queries" target="_blank">Read more on my blog</a>.</p>
  </div>
</section>

<!--
All the cards have the same html, no extra classnames are added to the wrapper or child elements, it uses container queries to change the look and feel based on their parent(container) width. 

When the CMS gives 3 items as an output
-->
<h2 class="subtitle">CMS outputs 3 items</h2>
<section class="container grid-cta">
  <div class="grid-cta-item">
    <article class="card-cta">
      <img src="https://picsum.photos/1600/900?random=1" alt="" />
      <div class="card-body">
        <h2>Call to action nr 1</h2>
        <p class="card-description">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras convallis sodales erat vel accumsan.</p>
        <a href="">Read more</a>
      </div>
    </article>
  </div>
  <div class="grid-cta-item">
    <article class="card-cta">
      <img src="https://picsum.photos/1600/900?random=2" alt="" />
      <div class="card-body">
        <h2>Call to action nr 2</h2>
        <p class="card-description">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras convallis sodales erat vel accumsan.</p>
        <a href="">Read more</a>
      </div>
    </article>
  </div>
  <div class="grid-cta-item">
    <article class="card-cta">
      <img src="https://picsum.photos/1600/900?random=3" alt="" />
      <div class="card-body">
        <h2>Call to action nr 3</h2>
        <p class="card-description">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras convallis sodales erat vel accumsan.</p>
        <a href="">Read more</a>
      </div>
    </article>
  </div>
</section>

<!-- When the CMS gives 2 items as an output -->
<h2 class="subtitle">CMS outputs 2 items</h2>
<section class="container grid-cta">
  <div class="grid-cta-item">
    <article class="card-cta">
      <img src="https://picsum.photos/1600/900?random=1" alt="" />
      <div class="card-body">
        <h2>Call to action nr 1</h2>
        <p class="card-description">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras convallis sodales erat vel accumsan.</p>
        <a href="">Read more</a>
      </div>
    </article>
  </div>
  <div class="grid-cta-item">
    <article class="card-cta">
      <img src="https://picsum.photos/1600/900?random=2" alt="" />
      <div class="card-body">
        <h2>Call to action nr 2</h2>
        <p class="card-description">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras convallis sodales erat vel accumsan.</p>
        <a href="">Read more</a>
      </div>
    </article>
  </div>
</section>

<!-- When the CMS gives 1 items as an output -->
<h2 class="subtitle">CMS outputs 1 item</h2>
<section class="container grid-cta">
  <div class="grid-cta-item">
    <article class="card-cta">
      <img src="https://picsum.photos/1600/900?random=1" alt="" />
      <div class="card-body">
        <h2>Call to action nr 1</h2>
        <p class="card-description">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras convallis sodales erat vel accumsan.</p>
        <a href="">Read more</a>
      </div>
    </article>
  </div>
</section>
/* basic styling of our card */
.card-cta {
  margin-bottom: 24px;
  border: 1px solid #444;
  background: rgba(25,35,51);
}

.card-body {
  padding: 1.4rem;
}

/* Setting up our cta grid */
.grid-cta {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  grid-gap: 1.4rem;
}

.grid-cta-item {
  container: cta/inline-size;
}

/* change style of our cards based on their container width */
@container cta (min-width: 560px) { 
  .card-cta {
    display: grid;
    gap: 1.4rem;
    grid-template-columns: 215px 1fr;
    padding: 1.4rem;
  }
  
  .card-body {
    padding: 0;
  }
}

@container cta (min-width: 700px) { 
  .card-cta {
    position: relative;
    display: block;
    padding: 0;
    border: 0;
  }
  
  .card-cta::after {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, .2);
    z-index: 1;
    content: '';
  }
  
  .card-body {
    position: absolute;
    top: 50%;
    left: 50%;
    max-width: 500px;
    text-align: center;
    transform: translate(-50%, -50%);
    z-index: 2;
  }
}

/* some basic styling */
* {
  box-sizing: border-box;
}

body {
  margin: 0;
  padding: 0;
  font-family: 'Lato', sans-serif;
  font-size: 1.2rem;
  line-height: 1.5;
  color: #FEFEFE;
  background: #1f2937;
}

img {
  max-width: 100%;
  margin: 0;
}

h1 {
  margin: 0 0 16px 0;
  font-family: 'Merriweather', serif;
  font-size: 2rem;
}

h2 {
  margin: 0 0 8px 0;
  font-family: 'Merriweather', serif;
  font-size: 1.4rem;
}

.subtitle {
  padding: 40px 30px 10px;;
  margin: 0;
  font-family: 'Merriweather', serif;
  font-size: 1.2rem;
  text-align: center;
  border-bottom: 1px dashed #555;
}

p {
  margin: 0 0 24px 0;
}

a {
  color: darkorange;
}

.demo-intro {
  font-size: 1.5rem;
  background: #111827;
}

.demo-intro p {
  margin: 0;
}

.container {
  max-width: 1300px;
  margin: 0 auto;
  padding: 40px 20px;
}
// Support Test (polyfill)
const supportsContainerQueries = "container" in document.documentElement.style;


if (!supportsContainerQueries) {
  import("https://cdn.skypack.dev/container-query-polyfill");
}
Run Pen

External CSS

  1. https://fonts.googleapis.com/css2?family=Lato&amp;family=Merriweather:wght@700&amp;display=swap

External JavaScript

This Pen doesn't use any external JavaScript resources.