(function(){ /* Script enfocado SOLO en móvil (<= 900px) para forzar que #container08 sea visible inmediatamente al cargar (sin necesidad de hacer scroll). - Quita temporalmente transform/filter/perspective/will-change en ancestros problemáticos. - Inserta reglas CSS con !important para forzar position:fixed. - Mueve el header al inicio del body si es necesario. - Ajusta body.paddingTop a la altura real del header. - Fuerza repaint con rAF+opacidad para Chrome mobile. - Restaura lo modificado si se vuelve a escritorio automáticamente. */ const MOBILE_BREAKPOINT = 900; /* <= 900px = móvil (ajusta si quieres otro valor) */ const DEBUG = false; /* pon true para ver logs en la consola */ function log(){ if(!DEBUG) return; console.log('[fixHeaderMobile]', ...arguments); } function isMobile(){ return window.innerWidth <= MOBILE_BREAKPOINT; } /* Inserta CSS con reglas !important para asegurar comportamiento fijo */ function ensureForceStyle(){ let st = document.getElementById('mobile-header-force-style'); if(st) return st; st = document.createElement('style'); st.id = 'mobile-header-force-style'; st.textContent = [ /* forzar header fijo y encima de todo */ '#container08.mobile-force { position: fixed !important; top: 0 !important; left: 0 !important; right: 0 !important; z-index: 2147483647 !important; transform: translateZ(0) !important; -webkit-transform: translateZ(0) !important; }', /* asegurar children del header no provoquen clipping */ '#container08.mobile-force * { -webkit-transform: none !important; transform: none !important; }' ].join('\n'); document.head.appendChild(st); return st; } /* Guardar state original del elemento (solo la primera vez) */ function saveHeaderOriginal(h){ if(!h) return; if(h.dataset.__origSaved) return; h.dataset.__origSaved = '1'; h.dataset.__origStyle = h.getAttribute('style') || ''; h.dataset.__origParent = h.parentNode ? (h.parentNode.tagName || 'NODE') : ''; h.dataset.__origNext = h.nextElementSibling ? (h.nextElementSibling.id || '') : ''; h.dataset.__origBodyPadding = document.body.style.paddingTop || ''; log('Cabecera: estado original guardado'); } /* Restaurar header (cuando volvamos a escritorio) */ function restoreHeader(h){ if(!h || !h.dataset.__origSaved) return; /* restaurar estilo inline */ try{ const s = h.dataset.__origStyle || ''; if(s.trim() === '') h.removeAttribute('style'); else h.setAttribute('style', s); }catch(e){ log('restoreHeader style', e); } /* restaurar padding del body */ try{ document.body.style.paddingTop = h.dataset.__origBodyPadding || ''; }catch(e){} /* eliminar clase forzada */ h.classList.remove('mobile-force'); /* quitar style tag si existe */ const st = document.getElementById('mobile-header-force-style'); if(st) st.remove(); /* limpiar marca */ delete h.dataset.__origSaved; delete h.dataset.__origStyle; delete h.dataset.__origParent; delete h.dataset.__origNext; delete h.dataset.__origBodyPadding; log('Cabecera restaurada a estado original'); } /* Detectar ancestros problemáticos y anular algunos estilos guardando originales */ function neutralizeAncestors(header){ const modified = []; let node = header.parentElement; while(node && node !== document.documentElement){ try{ const cs = window.getComputedStyle(node); const hasTransform = cs.transform && cs.transform !== 'none'; const hasPerspective = cs.perspective && cs.perspective !== 'none'; const hasFilter = cs.filter && cs.filter !== 'none'; const hasWill = cs.willChange && cs.willChange !== 'auto' && cs.willChange !== 'none'; if(hasTransform || hasPerspective || hasFilter || hasWill){ /* guardar inline original la primera vez */ if(node.dataset.__origAncStyle === undefined) node.dataset.__origAncStyle = node.getAttribute('style') || ''; /* anular propiedades que rompen fixed */ node.style.transform = 'none'; node.style.webkitTransform = 'none'; node.style.perspective = 'none'; node.style.filter = 'none'; node.style.willChange = 'auto'; modified.push(node); log('Anulado styles en ancestro', node); } }catch(e){ /* no bloquear por errores en computed style */ } node = node.parentElement; } return modified; } /* Restaurar ancestros modificados */ function restoreAncestors(modified){ if(!modified || !modified.length) return; modified.forEach(node=>{ try{ const orig = node.dataset.__origAncStyle || ''; if(orig.trim() === '') node.removeAttribute('style'); else node.setAttribute('style', orig); delete node.dataset.__origAncStyle; log('Ancestro restaurado', node); }catch(e){} }); } /* Forzar repintado con rAF + transición corta (muy efectivo en Chrome mobile) */ function forceRepaint(header){ if(!header) return; try{ header.style.willChange = 'transform, opacity'; header.style.webkitBackfaceVisibility = 'hidden'; header.style.backfaceVisibility = 'hidden'; header.style.visibility = 'hidden'; void header.offsetHeight; /* marcar clase que contiene reglas !important */ header.classList.add('mobile-force'); /* usar rAF para forzar animación */ requestAnimationFrame(()=>{ header.style.transition = 'opacity 120ms linear, transform 120ms linear'; header.style.opacity = '0.99'; header.style.visibility = 'visible'; requestAnimationFrame(()=>{ header.style.opacity = '1'; setTimeout(()=>{ header.style.transition = ''; }, 180); }); }); log('Repaint forzado'); }catch(e){ log('forceRepaint error', e); } } /* Ajustar padding-top del body según altura real del header */ function adjustBodyPadding(header){ try{ const rect = header.getBoundingClientRect(); const extra = 6; const pad = Math.ceil(rect.height + extra); document.body.style.paddingTop = pad + 'px'; log('padding-top ajustado a', pad); }catch(e){ log('adjustBodyPadding error', e); } } /* Función principal que aplica el fix SOLO en móvil */ let lastModifiedAncestors = []; function applyMobileFix(){ if(!isMobile()) return; const header = document.getElementById('container08'); if(!header) { log('No existe header'); return; } saveHeaderOriginal(header); ensureForceStyle(); /* mover al inicio del body para evitar que hermanos lo empujen */ try{ if(document.body.firstElementChild !== header) document.body.insertBefore(header, document.body.firstElementChild); }catch(e){ log('move header error', e); } /* neutralizar ancestros problemáticos y guardar la lista para restaurar luego */ lastModifiedAncestors = neutralizeAncestors(header); /* añadir clase que aplica reglas !important */ header.classList.add('mobile-force'); /* ajustar padding y forzar repaint */ adjustBodyPadding(header); forceRepaint(header); } /* Restaurar todo cuando no estemos en móvil */ function removeMobileFix(){ const header = document.getElementById('container08'); if(!header) return; /* restaurar ancestros si los tocamos */ restoreAncestors(lastModifiedAncestors || []); lastModifiedAncestors = []; /* restaurar header a su estado original */ restoreHeader(header); } /* Re-aplicar inteligentemente según viewport */ function update(){ if(isMobile()) applyMobileFix(); else removeMobileFix(); } /* Event listeners y re-intentos cortos para Carrd */ window.addEventListener('load', ()=>{ setTimeout(update, 60); setTimeout(update, 360); setTimeout(update, 900); }); window.addEventListener('resize', ()=>{ setTimeout(update, 80); }); window.addEventListener('orientationchange', ()=>{ setTimeout(update, 140); }); /* MutationObserver ligero: solo reintentar aplicando fix en móvil si Carrd reestructura */ if('MutationObserver' in window){ try{ const mo = new MutationObserver((mutations)=>{ if(isMobile()) setTimeout(applyMobileFix, 60); }); mo.observe(document.body, { childList: true, subtree: false }); }catch(e){} } /* Exponer helpers para debug si activar DEBUG=true */ window.__fixHeaderMobile = { applyMobileFix, removeMobileFix, update }; })();
Portfolio
Servicios
Sobre mi
Contacto
Estudio Audiovisual
en Alcalá de Henares
Tu visión hecha realidad: Vídeos, diseños y fotografías que marcan la diferencia.
Ver Portfolio
Empezar Un Proyecto