הטמעת כותרת/פוטר דביקים: מדריך קוד מלא

נאבקים עם header ו-footer קבועים שמפריעים למשתמשים ופוגעים במדדי האתר? אנחנו בונים ומיישמים headers ו-footers קבועים עם תמיכה בהסתרה בגלילה ובמובייל. הצוות שלנו מספק פתרונות turnkey—מביקורת ועד תמיכה שוטפת—ומבטיח ביצועים אמינים ויכולת scaling.

פיתוח ותחזוקה של כל סוגי האתרים:

אתרי מידע או יישומי אינטרנט
אתרי תדמית, דפי נחיתה, אתרי חברה, קטלוגים מקוונים, חידונים, אתרי קידום, בלוגים, מקורות חדשות, פורטלי מידע, פורומים, אגרגטורים
אתרי מסחר אלקטרוני או יישומי אינטרנט
חנויות מקוונות, פורטלי B2B, שווקים, בורסות מקוונות, אתרי קאשבק, בורסות, פלטפורמות דרופשיפינג, מנתחי מוצרים
יישומי אינטרנט לניהול תהליכים עסקיים
מערכות CRM, מערכות ERP, פורטלים ארגוניים, מערכות ניהול ייצור, מנתחי מידע
אתרי שירות אלקטרוני או יישומי אינטרנט
פלטפורמות מודעות, בתי ספר מקוונים, בתי קולנוע מקוונים, בוני אתרים, פורטלים לשירותים אלקטרוניים, פלטפורמות אירוח וידאו, פורטלים נושאיים

אלה רק חלק מהסוגים הטכניים של אתרים שאנו עובדים איתם, ולכל אחד מהם יכולים להיות מאפיינים ופונקציונליות ספציפיים משלו, וכן ניתן להתאים אותם לצרכים ולמטרות הספציפיים של הלקוח.

השירותים שאנו מציעים
מציג 1 מתוך 1כל 2062 השירותים
הטמעת כותרת/פוטר דביקים: מדריך קוד מלא
פשוט
~1 יום

הכישורים שלנו:

שאלות נפוצות

העבודות האחרונות

  • פיתוח אתר חברה B2B ADVANCE
    פיתוח אתר חברה B2B ADVANCE
    1504
  • פיתוח אפליקציית ווב עבור FEEDME
    פיתוח אפליקציית ווב עבור FEEDME
    1344
  • פיתוח אתר עבור BELFINGROUP
    פיתוח אתר עבור BELFINGROUP
    1052
  • פיתוח חנות מקוונת לחברת FURNORO
    פיתוח חנות מקוונת לחברת FURNORO
    1307
  • פיתוח אפליקציית ווב עבור Enviok
    פיתוח אפליקציית ווב עבור Enviok
    1050
  • פיתוח אתר לחברת FIXPER
    פיתוח אתר לחברת FIXPER
    1033

דמיינו אתר מסחר אלקטרוני עם 50,000 מוצרים. כותרת דביקה (sticky header) במהלך גלילה תופסת 10% מהמסך, מחמירה את LCP ב-1.5 שניות ומגדילה את CLS ל-0.25. במובייל, כפתור 'קנייה' מכוסה על ידי ניווט תחתון ללא safe-area. בעיות כאלה נפתרות עם קוד ברמת production שנבדק על אתרים עם 100 אלף+ סשנים ביום. אנחנו, צוות עם ניסיון של 10+ שנים בפיתוח אתרים, יישמנו אלמנטים דביקים ביותר מ-50 פרויקטים. בואו נפרק את היישום של כותרת/פוטר דביקים עם hide-on-scroll, React hook ותמיכה ב-iOS. אם אתם צריכים פתרון מוכן, הזמינו אותו turnkey עם אחריות ל-6 חודשים.

איך עובד position: sticky?

position: sticky הוא כלי בסיסי, אבל יש לו ניואנסים. קונטיינר האב לא צריך להכיל overflow: hidden, אחרת ההדבקה לא תעבוד. הוא לא תומך ב'בריחה' בגלילה למטה ועלול להתנגש עם offsets מותאמים אישית. לתרחישים פשוטים זה בסדר, למורכבים זה לא. לפי MDN, position: sticky הוא הכלאה בין relative ל-fixed.

CSS בסיסי לכותרת דביקה

/* Стили для sticky header */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: #fff;
  will-change: transform;
  transition: box-shadow 0.2s ease;
}

.site-header--scrolled {
  box-shadow: 0 2px 20px rgba(0, 0, 0, 0.1);
}

/* Hide-on-scroll: скрытие при прокрутке вниз */
.site-header--hidden {
  transform: translateY(-100%);
  transition: transform 0.3s ease;
}

/* Sticky footer с safe-area */
.bottom-nav {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 100;
  background: #fff;
  border-top: 1px solid #e2e8f0;
  padding-bottom: env(safe-area-inset-bottom);
  padding-bottom: max(env(safe-area-inset-bottom), 8px);
}

/* Sidebar с учётом высоты хедера */
:root {
  --header-height: 64px;
}

.sidebar {
  position: sticky;
  top: calc(var(--header-height) + 24px);
  max-height: calc(100vh - var(--header-height) - 48px);
  overflow-y: auto;
  overscroll-behavior: contain;
}

/* Anchor-ссылки: scroll-margin-top */
[id] {
  scroll-margin-top: calc(var(--header-height, 64px) + 16px);
}

למה transform יעיל יותר ל-hide-on-scroll?

שינוי /* Стили для sticky header */ .site-header { position: sticky; top: 0; z-index: 100; background: #fff; will-change: transform; transition: box-shadow 0.2s ease; } .site-header--scrolled { box-shadow: 0 2px 20px rgba(0, 0, 0, 0.1); } /* Hide-on-scroll: скрытие при прокрутке вниз */ .site-header--hidden { transform: translateY(-100%); transition: transform 0.3s ease; } /* Sticky footer с safe-area */ .bottom-nav { position: fixed; bottom: 0; left: 0; right: 0; z-index: 100; background: #fff; border-top: 1px solid #e2e8f0; padding-bottom: env(safe-area-inset-bottom); padding-bottom: max(env(safe-area-inset-bottom), 8px); } /* Sidebar с учётом высоты хедера */ :root { --header-height: 64px; } .sidebar { position: sticky; top: calc(var(--header-height) + 24px); max-height: calc(100vh - var(--header-height) - 48px); overflow-y: auto; overscroll-behavior: contain; } /* Anchor-ссылки: scroll-margin-top */ [id] { scroll-margin-top: calc(var(--header-height, 64px) + 16px); } לא גורם ל-reflow — הדפדפן מעבד אותו על GPU. זה מהיר פי 10+ משינוי transform או top. דפוס ה-hide-on-scroll: הסתר כותרת בגלילה למטה, הצג בגלילה למעלה. השתמשו ב-throttling דרך height כדי למזער עומס. יישום טיפוסי ב-JavaScript טבעי:

const header = document.querySelector('.site-header');
let lastScrollY = 0;
let scrollStart = 0;
let hidden = false;
const THRESHOLD = 100;
const HIDE_AFTER = 50;

function onScroll() {
    const y = window.scrollY;
    const diff = y - lastScrollY;
    if (diff > 0) {
        if (!hidden && y > THRESHOLD && y - scrollStart > HIDE_AFTER) {
            header.classList.add('site-header--hidden');
            hidden = true;
        }
    } else {
        if (hidden) {
            header.classList.remove('site-header--hidden');
            hidden = false;
            scrollStart = y;
        }
    }
    lastScrollY = y;
}

let ticking = false;
window.addEventListener('scroll', () => {
    if (!ticking) {
        requestAnimationFrame(() => {
            onScroll();
            ticking = false;
        });
        ticking = true;
    }
}, { passive: true });

איך ליישם hide-on-scroll עם React hook?

ב-React 18+ אנחנו משתמשים ב-hook מותאם אישית שמחזיר מצבים requestAnimationFrame ו-const header = document.querySelector('.site-header'); let lastScrollY = 0; let scrollStart = 0; let hidden = false; const THRESHOLD = 100; const HIDE_AFTER = 50; function onScroll() { const y = window.scrollY; const diff = y - lastScrollY; if (diff > 0) { if (!hidden && y > THRESHOLD && y - scrollStart > HIDE_AFTER) { header.classList.add('site-header--hidden'); hidden = true; } } else { if (hidden) { header.classList.remove('site-header--hidden'); hidden = false; scrollStart = y; } } lastScrollY = y; } let ticking = false; window.addEventListener('scroll', () => { if (!ticking) { requestAnimationFrame(() => { onScroll(); ticking = false; }); ticking = true; } }, { passive: true }); . זה מפחית re-renders פי 3–5 בהשוואה למניפולציה ישירה של DOM. הנה ה-hook המלא ודוגמת קומפוננטה:

import { useState, useEffect, useRef } from 'react';

interface StickyHeaderState {
  isScrolled: boolean;
  isVisible: boolean;
  scrollY: number;
}

function useStickyHeader(hideOnScrollDown = true): StickyHeaderState {
  const [state, setState] = useState<StickyHeaderState>({
    isScrolled: false,
    isVisible: true,
    scrollY: 0
  });
  const lastScrollY = useRef(0);
  const scrollStart = useRef(0);

  useEffect(() => {
    let ticking = false;
    const handler = () => {
      if (ticking) return;
      ticking = true;
      requestAnimationFrame(() => {
        const y = window.scrollY;
        const diff = y - lastScrollY.current;
        setState(prev => {
          let isVisible = prev.isVisible;
          if (hideOnScrollDown) {
            if (diff > 0 && y > 100 && y - scrollStart.current > 50) {
              isVisible = false;
            } else if (diff < 0) {
              if (!isVisible) scrollStart.current = y;
              isVisible = true;
            }
          }
          return {
            isScrolled: y > 10,
            isVisible,
            scrollY: y
          };
        });
        lastScrollY.current = y;
        ticking = false;
      });
    };
    window.addEventListener('scroll', handler, { passive: true });
    return () => window.removeEventListener('scroll', handler);
  }, [hideOnScrollDown]);

  return state;
}

export function SiteHeader() {
  const { isScrolled, isVisible } = useStickyHeader(true);
  return (
    <header
      className={[
        'site-header',
        isScrolled ? 'site-header--scrolled' : '',
        !isVisible ? 'site-header--hidden' : '',
      ]
        .filter(Boolean)
        .join(' ')}
    >
      {/* контент */}
    </header>
  );
}

איך למנוע חפיפה של תוכן על ידי כותרת דביקה עם קישורי עוגן?

הוסיפו מאפיין CSS isScrolled לכל האלמנטים עם id: isVisible. או השתמשו ב-JS לחישוב offset ו-import { useState, useEffect, useRef } from 'react'; interface StickyHeaderState { isScrolled: boolean; isVisible: boolean; scrollY: number; } function useStickyHeader(hideOnScrollDown = true): StickyHeaderState { const [state, setState] = useState<StickyHeaderState>({ isScrolled: false, isVisible: true, scrollY: 0 }); const lastScrollY = useRef(0); const scrollStart = useRef(0); useEffect(() => { let ticking = false; const handler = () => { if (ticking) return; ticking = true; requestAnimationFrame(() => { const y = window.scrollY; const diff = y - lastScrollY.current; setState(prev => { let isVisible = prev.isVisible; if (hideOnScrollDown) { if (diff > 0 && y > 100 && y - scrollStart.current > 50) { isVisible = false; } else if (diff < 0) { if (!isVisible) scrollStart.current = y; isVisible = true; } } return { isScrolled: y > 10, isVisible, scrollY: y }; }); lastScrollY.current = y; ticking = false; }); }; window.addEventListener('scroll', handler, { passive: true }); return () => window.removeEventListener('scroll', handler); }, [hideOnScrollDown]); return state; } export function SiteHeader() { const { isScrolled, isVisible } = useStickyHeader(true); return ( <header className={[ 'site-header', isScrolled ? 'site-header--scrolled' : '', !isVisible ? 'site-header--hidden' : '', ].filter(Boolean).join(' ')} > {/* контент */} </header> ); } ידני בלחיצה על קישורי עוגן. בלי זה, עוגנים יוסתרו מתחת לכותרת, מה שיחמיר את חוויית המשתמש.

מה זה safe-area-inset-bottom ואיך להשתמש בו?

לניווט תחתון במובייל השתמשו ב-scroll-margin-top עם scroll-margin-top: calc(var(--header-height) + 16px). ב-scrollTo הוסיפו position: fixed. פצו על הגובה בתוכן: env(safe-area-inset-bottom). זה מונע מתוכן להיות מכוסה על ידי פאנלים מערכתיים של iOS.

מה כלול בעבודה?

  • ביקורת על היישום הנוכחי של אלמנטים דביקים עם מדידת Core Web Vitals.
  • פיתוח פתרון מותאם אישית על הסטאק שלכם (React, Vue, Angular, או JS טבעי).
  • אינטגרציה עם הארכיטקטורה הקיימת, כולל SSR והגנת CSRF.
  • אופטימיזציית ביצועים: ביטול layout thrashing, מזעור reflow.
  • בדיקות על מכשירים אמיתיים (iPhone, Android, iPad) עם גרסאות דפדפן שונות.
  • תיעוד והדרכה למפתח שלכם.
  • תמיכה לאחר השקה למשך 6 חודשים.
תמיכת דפדפנים אלמנטים דביקים נתמכים בכל הדפדפנים המודרניים (Chrome 56+, Firefox 59+, Safari 8+, Edge 16+). עבור IE11 נדרש polyfill. Safe-area נתמך ב-Safari החל מ-iOS 11.

השוואת גישות: sticky לעומת fixed

פרמטר position: sticky position: fixed
בזרימה כן לא
תופס מקום כן לא
הידבקות בגלילה כל כיוון מיקום קבוע
ביצועים גבוהים גבוהים
תמיכה ב-hide-on-scroll נדרש JS נדרש JS

טעויות נפוצות ביישום אלמנטים דביקים

בעיה פתרון
לקונטיינר האב יש <head> הסירו <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"> או שנו את המבנה
padding-bottom: calc(60px + env(safe-area-inset-bottom)) לא מוגדר הגדירו overflow: hidden לאלמנט הדביק
חסר overflow: hidden הוסיפו z-index לביצועים
אין z-index: 100 במובייל השתמשו ב-will-change: transform בפוטר
קישורי עוגן ללא will-change: transform הוסיפו safe-area-inset-bottom לכל האלמנטים עם id
שימוש ב-env(safe-area-inset-bottom) או scroll-margin-top לאנימציית הסתרה השתמשו ב-scroll-margin-top

תהליך עבודה

  1. אנליטיקה — ביקורת על ההתנהגות הנוכחית ו-Core Web Vitals. מדידת LCP, CLS, INP.
  2. עיצוב — בחירת גישה (sticky/hide-on-scroll), שיקול mobile-first.
  3. יישום — כתיבת קוד עם אינטגרציה לפרויקט שלכם. שימוש בסטאק מודרני (React 18, TypeScript, CSS Modules).
  4. בדיקות — בדיקה על מכשירים אמיתיים (iPhone, Android, iPad), מדידת מדדים.
  5. השקה — מסירת קוד, תיעוד, הדרכת המפתח שלכם.

לוח זמנים ועלות

לוח זמנים ליישום — מ-3 עד 7 ימי עבודה תלוי במורכבות. העלות מחושבת באופן אישי. אתם חוסכים על תיקון שגיאות שהיו מתרחשות ביישום עצמי. צרו קשר להערכת פרויקט — קבלו ייעוץ וחישוב מקדים תוך יום אחד. הזמינו יישום אלמנטים דביקים turnkey עם אחריות ל-6 חודשים.