問題起因
之前公司網站在加入預先載入動畫 (preload animation) 後,原本的選單無法正常置頂。
檢查了一下,發現增加了 sticky 類型項目選單的上層 div 元素高度是 0。原本嘗試賦予 height 值,但是無法發揮任何效果。

後來參考了這篇文章,內容說明「上層元素如果有 transform 的屬性值,那麼 position:fixed;
的設定則會無效。」
這樣的說法其實蠻合理的,因為 transform 會改變元素的大小、位置與旋轉角度,而 position 這個屬性值,是根據上層元素作為參考點,因此在會根據變形後的上層元素重新定位參考點,以 position: fixed;
為例,在 #page 擁有 transform 的屬性值後,其參考點會根據 #page 的 translate(0px, 0px) 作為起始座標,而不再是畫面的 (0, 0) 作為起始座標。
檢查了一下 html,果然出現這項屬性值。

造成這個問題的原因,可能是在增加動畫時,定義了上層元素 #page 的 transform 屬性值,藉此製作內容淡入、向上浮出的效果。
解決方法有 2 種:
方法一:避免一開始賦予上層元素 transform 屬性值
將第 14 行的 #page 選擇器改為其他元素,甚至直接拿掉。
(function($) { var tl = new TimelineMax(); setTimeout(function(){ var rule = CSSRulePlugin.getRule(".dark-mode .feature-img .text-underline::after"); tl.to("#logo_preload", {duration: 0.3,opacity:0}) .to("#preload", {duration: 0.1, backgroundColor: "transparent" }) .to("#bars", {duration:0.3,opacity:1}, "-=0.25") .to("#bar1", {duration:0.3,width:0}, "-=0.1") .to("#bar2", {duration:0.3,width:0}, "-=0.2") .to("#bar3", {duration:0.3,width:0}, "-=0.2") .to("#bar4", {duration:0.3,width:0}, "-=0.2") .to("#bar5", {duration:0.3,width:0}, "-=0.2") .to("#preload", {duration: 0.3, height:0}, "-=0.2") .fromTo("#page", 0.5, {opacity: 0, y: 50}, {opacity: 1, y: 0}, "-=0.8") .to(rule, {duration: 0.5, cssRule: {width: "100%"}}) }, time); })(jQuery);
方法二:事後移除掉 transform 屬性值
這種方法是在堅持必須要維持 #page 動畫的情況下才需要做,但是因為本身是另外一項操作,可能會影響效能表現,而且這個做法可能會連帶影響到其他對於 #page 的樣式操作。因此應該是第一種方法更好。
(function ($) { $(document).ready(function () { $( window ).on( 'scroll', function() { if ($(window).scrollTop() >= $("#wpadminbar").height() + $(".site-header").height()) { $('#sticky').addClass( 'sticky' ); $('#page').removeAttr( 'style' ); } else { $('#sticky').removeClass( 'sticky' ); } }); }); })(jQuery);
後記
目前提出的都是暫時解法,目的在於解決 position: fixed;
元素的上層元素中,有 transform 的屬性值。這是造成問題的根源,因此未來在使用 position: fixed;
的時候必須格外注意。
發佈留言