Critical: Fixing Layout Shift, Loading Lag and Responsive CSS in Custom Liquid

Hi everyone,

I’ve developed a custom Hero section for my Shopify store (Dawn theme) using a Custom Liquid block. I’m aiming for a premium feel, but I’m hitting some technical walls regarding performance and responsiveness that I can’t seem to solve.

The Main Issues:

  1. Layout Shift & Jumping: When the page loads, the section height jumps and elements “pop” into place. It’s not a smooth experience.

  2. Loading Lag: Even though my video files are small (under 2MB) and I use poster images, there is a visible delay/flicker before the video starts and before the custom fonts/styling render.

  3. Responsive Scaling: I need to ensure this layout scales perfectly from the smallest iPhone to 4K monitors. Currently, I’m worried about text overlapping or the “glowing sapphire line” looking off on certain screen widths.

What I need help with:

  • How can I eliminate the “jump” during load (CLS)?

  • Is there a better way to preload the poster images/fonts so they are visible instantly?

  • How can I optimize the CSS/Media Queries in my code below to ensure it’s “buttery smooth” and perfectly responsive on all devices?

Here is my current code:

<div class="hero-video-box js-video-container">
  
  <div class="hero-content-inner">
    <h1 class="main-hero-title">
      להחזיר את החופש<br>
      <span class="glow-blue-text">לכל תנועה</span>
    </h1>

    <div class="cta-wrapper">
      <a href="/products/orela-knee-pro" class="pakal-style-button">
        לרכישה עכשיו
        <span class="arrow-svg">←</span>
      </a>
    </div>
  </div>

  <video autoplay muted loop playsinline webkit-playsinline preload="auto"
         id="heroVidDesktop"
         class="hero-video-obj desktop-video"
         poster="https://cdn.shopify.com/s/files/1/0669/1667/9723/files/Home_Page_1.jpg?v=1775259776">
    <source src="https://cdn.shopify.com/videos/c/o/v/1f331cd02a5b4666ae15afb3ee97780c.mp4" type="video/mp4">
  </video>

  <video autoplay muted loop playsinline webkit-playsinline preload="auto"
         id="heroVidMobile"
         class="hero-video-obj mobile-video"
         poster="https://cdn.shopify.com/s/files/1/0669/1667/9723/files/Home_Page.jpg?v=1775259778">
    <source src="https://cdn.shopify.com/videos/c/o/v/99db697b57834f349d4c13272dbd0a2b.mp4" type="video/mp4">
  </video>

  <div class="hero-video-overlay"></div>
</div>

<div class="benefits-luxury-strip">
  <div class="benefit-column">
    <div class="b-text-wrap">
      <span class="b-title-bold">משלוח חינם!</span>
      <span class="b-sub-text">עד הבית</span>
    </div>
    <div class="sapphire-glow-line"></div>
  </div>
  
  <div class="benefit-column">
    <div class="b-text-wrap">
      <span class="b-title-bold">2237+</span>
      <span class="b-sub-text">לקוחות מרוצים</span>
    </div>
    <div class="sapphire-glow-line"></div>
  </div>

  <div class="benefit-column">
    <div class="b-text-wrap">
      <span class="b-title-bold">14 ימי נסיון</span>
      <span class="b-sub-text">ללא התחייבות</span>
    </div>
    <div class="sapphire-glow-line"></div>
  </div>
</div>

<
/* — התיקון למניעת הגליץ’ והתאמת הבהירות (השינוי כאן) — /
.hero-video-box {
position: relative;
width: 100%;
flex-grow: 1;
display: flex;
align-items: center;
justify-content: center;
background-color:
#000*;
background-size: cover;
background-repeat: no-repeat;
z-index: 1; /* הכנה לשכבת הכהות /
}
/
שכבת הכהות עבור פוסטר ה-CSS (מייצר brightness 0.6) /
.hero-video-box::after {
content: ‘’;
position: absolute;
inset: 0;
background-color: rgba(0, 0, 0, 0.4); /
מכהה ב-40%, משאיר 60% בהירות /
z-index: 0; /
מתחת לתוכן, מעל הרקע /
}
/
רקע לדסקטופ /
@media screen and (min-width: 769px) {
.hero-video-box {
background-image: url(‘https://cdn.shopify.com/s/files/1/0669/1667/9723/files/Home_Page_1.jpg?v=1775259776’);
background-position: top center;
}
}
/
רקע למובייל /
@media screen and (max-width: 768px) {
.hero-video-box {
background-image: url(‘https://cdn.shopify.com/s/files/1/0669/1667/9723/files/Home_Page.jpg?v=1775259778’);
background-position: center center;
}
}
/
— העיצוב המקורי שלך ללא שינוי בערכים — */
.orela-full-wrapper, .orela-full-wrapper h1, .orela-full-wrapper span, .orela-full-wrapper a {
font-family: inherit !important;
-webkit-font-smoothing: antialiased;
text-rendering: optimizeSpeed;
}
.orela-full-wrapper {
width: 100%; height: calc(100vh - 120px); position: relative;
background: #000; overflow: hidden; opacity: 1 !important;
}
.orela-complete-section {
width: 100%; height: 100%;
direction: rtl; display: flex; flex-direction: column;
}
.hero-video-obj {
position: absolute; top: 0; left: 0; width: 100%; height: 100%;
object-fit: cover; filter: brightness(0.6); outline: none; border: none;
z-index: 1; pointer-events: none;
background: transparent;
}
.desktop-video { display: block; object-position: top center; }
.mobile-video { display: none; }
@media screen and (max-width: 768px) {
.desktop-video { display: none; }
.mobile-video { display: block; object-position: center center; }
.orela-full-wrapper { height: calc(100vh - 185px); }
}
.hero-video-overlay {
position: absolute; inset: 0; z-index: 2; pointer-events: none;
background: radial-gradient(circle, transparent 20%, rgba(0,0,0,0.7) 100%);
}
.hero-content-inner {
position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
width: 100%; z-index: 10; text-align: center; color: #fff; padding: 0 20px;
margin: 0; backface-visibility: hidden;
}
.main-hero-title {
font-size: clamp(28px, 4vw, 48px); font-weight: 900; line-height: 1.1;
margin: 0 0 20px 0; letter-spacing: -1px; color: #fff !important;
text-shadow: 0 2px 10px rgba(0,0,0,0.8); display: block; min-height: 2.2em;
}
.glow-blue-text { color: #4ba3f5; }
.pakal-style-button {
display: inline-flex; align-items: center; gap: 10px;
background: #4ba3f5; color: #000 !important;
padding: 14px 45px; border-radius: 100px;
font-size: 18px; font-weight: 800; text-decoration: none;
box-shadow: 0 4px 15px rgba(75, 163, 245, 0.4);
transition: transform 0.2s ease;
}
.benefits-luxury-strip {
background: linear-gradient(180deg, #161a1d 0%, #000000 100%);
display: flex; flex-direction: row; justify-content: space-around;
padding: 15px 5%; border-top: 1px solid #222; flex-shrink: 0; z-index: 11;
}
.benefit-column { display: flex; flex-direction: column; align-items: center; text-align: center; flex: 1; }
.b-text-wrap { display: flex; flex-direction: column; align-items: center; margin-bottom: 8px; gap: 4px; }
.b-title-bold { color: #fff; font-weight: 700; font-size: 19px; white-space: nowrap; line-height: 1; }
.b-sub-text { color: rgba(255,255,255,0.9); font-size: 14px; font-weight: 400; line-height: 1.1; }
.sapphire-glow-line {
width: 60px; height: 2px; background: #ffffff; border-radius: 10px;
box-shadow: 0 0 8px #4ba3f5, 0 0 15px #4ba3f5, 0 2px 10px rgba(75, 163, 245, 0.9);
display: block !important; visibility: visible !important;
}
@media screen and (min-width: 769px) {
.main-hero-title { font-size: 54px; margin-bottom: 30px; }
.pakal-style-button { padding: 18px 55px; font-size: 20px; }
.pakal-style-button:hover { transform: translateY(-2px) scale(1.02); }
.sapphire-glow-line { width: 75px; height: 3px; }
}
@media screen and (max-width: 768px) {
.benefits-luxury-strip { gap: 10px; padding: 15px 2%; }
.pakal-style-button { padding: 12px 35px; font-size: 16px; }
.b-title-bold { font-size: 16px; font-weight: 800; }
.sapphire-glow-line { width: 35px; }
}

Any advice on how to clean this up for professional-grade performance would be greatly appreciated!

Hey @Aborela ,
You are actually dealing with some pretty normal issues when building a custom hero like this especially with video and fonts involved.

For the layout shift the main reason is the browser doesnt know how much space to reserve before everything loads.
Try giving your hero section a fixed or minimum height from the start like min-height: 100vh. That alone usually removes the jump.

For the video flicker even small videos can lag a bit. The best way to handle this is to rely more on a good poster image that loads instantly and let the video quietly take over after. Also make sure the poster and video have the same aspect ratio so there’s no visual shift.

The font delay is likely causing that pop-in effect too. If youre using custom fonts make sure you’re using font-display: swap and ideally preload your main font. That way text shows immediately instead of waiting.

For responsiveness avoid fixed sizes as much as possible. Using something like clamp() for font sizes and spacing helps things scale smoothly across devices without breaking layouts.

@Aborela
Hey this is a solid setup, you’re just running into a few common video hero issues.

  1. Layout jump (CLS)
    Happening due to 100vh + absolute positioning + font load.
    Try:

.hero-video-box { min-height: 100svh; }

  1. Video flicker
    preload=“auto” on both videos is causing delay.
    Use metadata and show video only after it’s ready (keep poster for first paint).

  2. Both videos loading
    Desktop + mobile videos load together unnecessary.
    Use one video with media-based sources or load conditionally.

  3. Fonts shift layout
    Preload fonts + use font-display: swap.

  4. Small bug

background-color: #000*; The * is likely breaking that rule.

You’re very close once you stabilize the initial layout and control when media appears, it’ll feel much smoother.

thank you all for your help!!! i was able to fix the issues you pointed out.