<header>
  <input type="text" placeholder="Start typing to see how the footer stays at the bottom..." class="jsHandleInput" autofocus>
</header>
<main>
  <ul class="products jsTargetLiContainer">
    <li>This example shows that the footer and header can be "sticky" in the case when no content on the page. It saves from jumping footer and make UX better. Start typing ^^.</li>
  </ul>
</main>
<footer>I am a sticky footer. I don't care how many contents on the page.</footer>
html, body {
  height: 100%;
  box-sizing: border-box;
}

*, *::before, *::after {
    box-sizing: inherit;
}

/** That's all what you need to be happy. */

body {
  display: flex;
  flex-direction: column;
}

header {
  flex-shrink: 0;
  width: 100%;
  background: blue;
  padding: 16px;
  text-align: center;
}

main {
  flex: 1 0 auto;
  margin: 16px auto;
  width: 100%;
  max-width: 1280px;
}

footer {
  height: 50px;
  flex-shrink: 0;
  width: 100%;
  background: yellow;
  padding: 16px;
  text-align: center;
}

/** ^^ That's all what you need to be happy. */

input {
  padding: 16px;
  width: 100%;
  font-size: 24px;
}

.products {
  display: flex;
  flex-wrap: wrap;
}

.products li {
  width: 25%;
  padding: 8px;
}

.products img {
  width: 100%;
  height: auto;
}
View Compiled
const MAX_POSSIBLE_LI = 10;
const input = document.querySelector('.jsHandleInput');

input.addEventListener('input', function (e) {
  
  const randomArraySize = [...Array(Math.round(Math.random() * MAX_POSSIBLE_LI))];
  const randomLi = randomArraySize.map(() => '<li><img src="http://via.placeholder.com/500x200"></li>').join('');
    
  document.querySelector('.jsTargetLiContainer').innerHTML = randomLi;
});
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.