首頁 >web前端 >css教學 >以薩斯為中心

以薩斯為中心

尊渡假赌尊渡假赌尊渡假赌
尊渡假赌尊渡假赌尊渡假赌原創
2025-02-24 10:58:11304瀏覽

Centering With Sass

核心要點

  • CSS中的居中,特別是垂直居中,可能很棘手。 Sass可以將各種CSS居中方法封裝到一個易於使用的mixin中。
  • 居中方法取決於元素尺寸是否已知。如果未知,則使用CSS轉換以提高靈活性;如果已知,則使用負邊距。 Sass mixin將元素的左上角定位在容器的中間,然後將其向後移動其寬度和高度的一半。
  • 可以通過包含@supports規則來檢查CSS轉換支持,或對參數進行更嚴格的檢查以確保它們是寬度和高度的有效值,從而進一步改進mixin。
  • Flexbox是將元素在其父元素中居中的另一種解決方案。如果條件允許,它更容易使用。 Flexbox通過在父元素上設置三個屬性來居中子元素。

CSS居中一直以來都是一項繁瑣的任務,甚至成為該語言的一個笑柄,導致諸如“我們成功地將宇航員送上月球,但我們無法在CSS中進行垂直對齊”之類的笑話。

雖然CSS在處理居中,特別是垂直居中時確實有點棘手,但我認為這些笑話有點不公平。實際上,CSS中有很多方法可以居中內容,你只需要知道如何去做。

本文並非旨在解釋這些方法的工作原理,而是說明如何將它們封裝在Sass mixin中以方便易用。因此,如果您對CSS居中感到有些不舒服,我建議您事先閱讀一些資源:

  • 如何在CSS中居中
  • CSS居中:完整指南

準備好了嗎?讓我們開始吧。

概述

首先,我們將重點關注將元素在其父元素中居中,因為這是絕對居中最常見的用例(模態框、部分內容等)。當您詢問某人關於CSS居中的問題時,通常得到的回復是:您知道元素的尺寸嗎? 原因是,如果您不知道元素尺寸,最佳解決方案是依賴CSS轉換。這會稍微降低瀏覽器支持度,但它非常靈活。如果您無法使用CSS轉換或知道元素的寬度和高度,那麼很容易依賴負邊距。

因此,我們的mixin將基本上執行以下操作:將元素的左上角絕對定位在容器的中間,然後根據是否將尺寸傳遞給mixin,使用CSS轉換或負邊距將其向後移動其寬度和高度的一半。無尺寸:使用轉換;有尺寸:使用邊距。

然後您可以像這樣使用它:

<code>/**
 * 为子元素启用位置上下文
 */
.parent {
  position: relative;
}

/**
 * 将元素在其父元素中绝对居中
 * 没有将尺寸传递给mixin,因此它依赖于CSS转换
 */
.child-with-unknown-dimensions {
  @include center;
}

/**
 * 将元素在其父元素中绝对居中
 * 将宽度传递给mixin,因此我们对水平轴使用负边距,对垂直轴使用CSS转换
 */
.child-with-known-width {
  @include center(400px);
}

/**
 * 将元素在其父元素中绝对居中
 * 将高度传递给mixin,因此我们对垂直轴使用负边距,对水平轴使用CSS转换
 */
.child-with-known-height {
  @include center($height: 400px);
}

/**
 * 将元素在其父元素中绝对居中
 * 将宽度传递给mixin,因此我们对水平轴和垂直轴都使用负边距
 */
.child-with-known-dimensions {
  @include center(400px, 400px);
}</code>

編譯後,它應該輸出以下內容:

<code>.parent {
  position: relative;
}

.child-with-unknown-dimensions {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

.child-with-known-width {
  position: absolute;
  top: 50%;
  left: 50%;
  margin-left: -200px;
  width: 400px;
  transform: translateY(-50%);
}

.child-with-known-height {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translateX(-50%);
  margin-top: -200px;
  height: 400px;
}

.child-with-known-dimensions {
  position: absolute;
  top: 50%;
  left: 50%;
  margin-left: -200px;
  width: 400px;
  margin-top: -200px;
  height: 400px;
}</code>

好的,這看起來有點冗長,但請記住,此輸出僅用於演示目的。在給定情況下,您不太可能發現自己同時使用所有這些方法。

構建mixin

好的,讓我們深入研究。從之前的代碼片段中,我們已經知道mixin的簽名:它有兩個可選參數,$width$height

<code>/**
 * 为子元素启用位置上下文
 */
.parent {
  position: relative;
}

/**
 * 将元素在其父元素中绝对居中
 * 没有将尺寸传递给mixin,因此它依赖于CSS转换
 */
.child-with-unknown-dimensions {
  @include center;
}

/**
 * 将元素在其父元素中绝对居中
 * 将宽度传递给mixin,因此我们对水平轴使用负边距,对垂直轴使用CSS转换
 */
.child-with-known-width {
  @include center(400px);
}

/**
 * 将元素在其父元素中绝对居中
 * 将高度传递给mixin,因此我们对垂直轴使用负边距,对水平轴使用CSS转换
 */
.child-with-known-height {
  @include center($height: 400px);
}

/**
 * 将元素在其父元素中绝对居中
 * 将宽度传递给mixin,因此我们对水平轴和垂直轴都使用负边距
 */
.child-with-known-dimensions {
  @include center(400px, 400px);
}</code>

繼續。在任何情況下,mixin都需要使元素絕對定位,因此我們可以從這一點開始。

<code>.parent {
  position: relative;
}

.child-with-unknown-dimensions {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

.child-with-known-width {
  position: absolute;
  top: 50%;
  left: 50%;
  margin-left: -200px;
  width: 400px;
  transform: translateY(-50%);
}

.child-with-known-height {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translateX(-50%);
  margin-top: -200px;
  height: 400px;
}

.child-with-known-dimensions {
  position: absolute;
  top: 50%;
  left: 50%;
  margin-left: -200px;
  width: 400px;
  margin-top: -200px;
  height: 400px;
}</code>

我們將必須巧妙地編寫代碼。讓我們在這裡暫停一下,分析一下我們擁有的不同選項:

宽度 高度 解决方案
未定义 未定义 translate
定义 定义 margin
定义 未定义 margin-left translateY
未定义 定义 translateX margin-top

讓我們用這個。

<code>/**
 * 为子元素启用位置上下文
 */
.parent {
  position: relative;
}

/**
 * 将元素在其父元素中绝对居中
 * 没有将尺寸传递给mixin,因此它依赖于CSS转换
 */
.child-with-unknown-dimensions {
  @include center;
}

/**
 * 将元素在其父元素中绝对居中
 * 将宽度传递给mixin,因此我们对水平轴使用负边距,对垂直轴使用CSS转换
 */
.child-with-known-width {
  @include center(400px);
}

/**
 * 将元素在其父元素中绝对居中
 * 将高度传递给mixin,因此我们对垂直轴使用负边距,对水平轴使用CSS转换
 */
.child-with-known-height {
  @include center($height: 400px);
}

/**
 * 将元素在其父元素中绝对居中
 * 将宽度传递给mixin,因此我们对水平轴和垂直轴都使用负边距
 */
.child-with-known-dimensions {
  @include center(400px, 400px);
}</code>

現在我們已經為mixin設置了框架,我們只需要用實際的CSS聲明來填補空白。

<code>.parent {
  position: relative;
}

.child-with-unknown-dimensions {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

.child-with-known-width {
  position: absolute;
  top: 50%;
  left: 50%;
  margin-left: -200px;
  width: 400px;
  transform: translateY(-50%);
}

.child-with-known-height {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translateX(-50%);
  margin-top: -200px;
  height: 400px;
}

.child-with-known-dimensions {
  position: absolute;
  top: 50%;
  left: 50%;
  margin-left: -200px;
  width: 400px;
  margin-top: -200px;
  height: 400px;
}</code>

注意:#{0 0}技巧是一個不太乾淨的技巧,用於防止Sass進行稍微過於激進的壓縮,這會導致margin: mt 0 ml而不是margin: mt 0 0 ml

到目前為止,一切順利。

更進一步

我們可以做幾件事來進一步改進我們的mixin,例如在mixin中包含一個@supports規則來檢查CSS轉換支持,或者假設存在(或允許)Modernizr並根據是否支持CSS轉換來輸出條件樣式。我們還可以對參數進行更嚴格的檢查,以確保它們是寬度和高度的有效值。

但是,您必須問自己,這樣做是否是一件好事。 mixin本身的循環複雜度已經達到6,對於Sass輔助函數來說已經相當多了。它仍然可以接受,但是向其中添加更多代碼可能會導致循環複雜度進一步增加。

Flexbox怎麼樣?

我很確定你們中的一些人正在座位上跳躍,思考我們如何使用Flexbox將元素在其父元素中居中。確實,這是可能的,而且事實證明,如果條件允許,這是所有解決方案中最簡單的。

我們剛剛設置的解決方案和Flexbox解決方案之間的主要區別在於,後者建立在父元素之上,而前者主要關注子元素(前提是它的任何祖先的位置都不同於static)。

為了使元素使其子元素居中,您只需要設置三個屬性。您可以為此創建一個mixin、佔位符、類或任何您喜歡的元素。

<code>/// 在其父元素中水平、垂直或绝对居中元素
/// 如果指定,此mixin将根据元素的尺寸使用负边距。否则,它将依赖于CSS转换,CSS转换的浏览器支持度较低,但由于它们与尺寸无关,因此更灵活。
///
/// @author Kitty Giraudel
///
/// @param {Length | null} $width [null] - 元素宽度
/// @param {Length | null} $height [null] - 元素高度
///
@mixin center($width: null, $height: null) { .. }</code>

假設您添加了相關的供應商前綴(通過mixin或Autoprefixer),此解決方案應該在許多瀏覽器中“正常工作”。

<code>@mixin center($width: null, $height: null) {
  position: absolute;
  top: 50%;
  left: 50%;

  // 更多魔法在这里...
}</code>

正如您肯定猜到的那樣,它會產生:

<code>@mixin center($width: null, $height: null) {
  position: absolute;
  top: 50%;
  left: 50%;

  @if not $width and not $height {
    // 使用 `translate`
  } @else if $width and $height {
    // 使用 `margin`
  } @else if not $height {
    // 使用 `margin-left` 和 `translateY`
  } @else {
    // 使用 `margin-top` 和 `translateX`
  }
}</code>

最終想法

我們想要一個簡短的mixin來輕鬆地將元素在其父元素中居中;這個mixin可以完成這項工作,而且做得很好。它不僅足夠聰明,無論元素是否具有特定尺寸都能工作,而且還提供了一個友好且直觀的API,這非常重要。

通過查看代碼,任何人都可以立即理解@include center行是包含一個輔助函數,該輔助函數執行一些邏輯以使元素在其父元素中居中。但是請記住,為了使此方法有效,後者(或DOM樹中的任何父元素)必須具有不同於static的位置! ;)

您可以在SassMeister上使用此代碼:https://www.php.cn/link/780bc6caf343bb06a4372c0821012624

(由於篇幅限制,此處省略了FAQs部分。 FAQs部分內容與文章內容高度重複,可以根據需要自行添加或修改。)

以上是以薩斯為中心的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn