Physical Address

304 North Cardinal St.
Dorchester Center, MA 02124

使用 position: fixed 卻無法固定元素位置

問題起因

之前公司網站在加入預先載入動畫 (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; 的時候必須格外注意。

參考資料

Eric Chuang
Eric Chuang

正職是廣告行銷人員,因為 Google Tag Manager 的關係開始踏入網站製作的領域,進一步把 WordPress 當成 PHP + HTML + CSS + JavaScript 的學習教材。此外,因為工作的關係,曾經用 Automattic 的 Underscores (_s) 替客戶與公司官網進行全客製化佈景主題開發。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料