前幾天把 SCSS 的結構、Partial、@import,還有 compilerconfig.json 都整理過一輪。
我原本以為到這裡就差不多了:
寫 SCSS
↓
編譯成功
↓
畫面改變
結果實際改專案時才發現,事情沒有這麼直接。
我明明修改的是:
.scss
但瀏覽器根本不認識我專案裡這些 SCSS 原始檔。
真正被瀏覽器載入的是:
.css
所以中間其實還隔著好幾層。
如果其中任何一層沒有接起來,就很容易遇到:
SCSS 明明改了
編譯也成功了
結果瀏覽器完全沒變
這篇就來把「SCSS 到底怎麼一路跑到畫面上」完整追一次。
SCSS 是開發時比較方便撰寫的樣式語法。
例如我可能寫:
.page {
padding: 24px;
.title {
font-size: 24px;
font-weight: bold;
}
}
但瀏覽器實際需要的是 CSS。
所以編譯後可能變成:
.page {
padding: 24px;
}
.page .title {
font-size: 24px;
font-weight: bold;
}
真正的流程是:
SCSS
↓
Compiler
↓
CSS
↓
HTML 載入 CSS
↓
瀏覽器套用樣式
所以:
SCSS 有修改
不代表:
瀏覽器一定會跟著改變
因為還要確認後面每一段都有接上。

企業專案裡通常不會只有一支 SCSS。
可能會看到:
scss
├── styles.scss
├── _variables.scss
├── _header.scss
├── _sidebar.scss
└── pages
└── _home.scss
例如我要改首頁:
.home-page {
padding: 24px;
}
可能實際寫在:
_home.scss
但 _home.scss 通常不是直接給瀏覽器使用的。
它可能只是其中一個 Partial。
也就是說,我先要知道:
我現在修改的這支 SCSS,到底有沒有被主要入口檔載入?
例如入口檔是:
styles.scss
裡面可能有:
@import "variables";
@import "header";
@import "sidebar";
@import "pages/home";
這樣:
_home.scss
才會被一起編譯進:
styles.css
流程會變成:
_home.scss
↓
被 styles.scss 引入
↓
styles.scss 被編譯
↓
styles.css
如果我建立了一支:
_user.scss
卻忘記在入口檔引入:
@import "pages/user";
那就算 _user.scss 裡面寫了很多樣式,也可能完全不會進到最後的 CSS。
這時候問題不是瀏覽器。
甚至也不是 Compiler 壞掉。
只是:
這支 SCSS 根本沒有進到編譯流程裡
這也是為什麼前面學入口檔和 Partial 很重要。
compilerconfig.json 到底編譯哪一支?上一篇整理過 compilerconfig.json。
例如:
[
{
"outputFile": "wwwroot/css/styles.css",
"inputFile": "scss/styles.scss"
}
]
可以拆成:
inputFile
scss/styles.scss
↓ 編譯
outputFile
wwwroot/css/styles.css
所以 Compiler 不是看到所有 .scss 就全部自己猜著編譯。
它會依照設定,把指定的入口 SCSS 編譯成指定的 CSS。

(需依照專案實際路徑)
看到畫面沒變時,我會先確認:
我修改的 SCSS
↓
有沒有被入口檔引入?
入口檔
↓
是不是 compilerconfig.json 的 inputFile?
編譯後的 CSS
↓
是不是我以為的那一支?
這一步非常重要。
不要只看到:
Compile 成功
就直接相信畫面應該會改。
我會打開編譯後的 CSS,例如:
wwwroot/css/styles.css
直接搜尋剛才新增的樣式:
.home-page {
padding: 24px;
}
如果搜尋不到,就代表問題還在:
SCSS
↓
Compiler
↓
CSS
這一段。
可能是:
修改錯 SCSS
沒有被 @import
compilerconfig.json 指到另一支入口檔
沒有重新編譯
編譯輸出到另一個位置
反過來,如果 CSS 裡已經看到:
.home-page {
padding: 24px;
}
至少可以確認:
SCSS
↓
CSS
這段是成功的。
接下來就要追:
瀏覽器到底有沒有載入這支 CSS?
一般 HTML 會用:
<link rel="stylesheet" href="/css/styles.css">
載入 CSS。
但 MVC 專案裡,我一開始會以為這行應該出現在:
Index.cshtml
結果打開後卻完全找不到。
例如 Index.cshtml 可能只有:
<div class="home-page">
<h1>首頁</h1>
</div>
那 CSS 到底在哪裡載入?
這時候可以全域搜尋:
styles.css
或:
<link rel="stylesheet"
很可能最後會找到:
_Layout.cshtml
裡面有:
<link rel="stylesheet" href="~/css/styles.css" />
這時我才開始理解:
Index.cshtml
不一定負責載入整個網站的 CSS
_Layout.cshtml
可能已經統一把共用 CSS 載入了

這也剛好帶出下一篇會講的 _Layout.cshtml。
~ 又是什麼?MVC 裡可能會看到:
<link rel="stylesheet" href="~/css/styles.css" />
這個:
~
可以先理解成 Web 應用程式的根路徑。
所以:
~/css/styles.css
是在指網站底下的:
css/styles.css
而靜態檔案通常會放在:
wwwroot
因此專案檔案可能是:
wwwroot
└── css
└── styles.css
瀏覽器請求的網址則會類似:
/css/styles.css
可以先這樣理解:
專案裡
wwwroot/css/styles.css
↓
瀏覽器
/css/styles.css
到了這一步,就不能只看 Visual Studio。
可以打開瀏覽器開發者工具。
按:
F12
進入:
Network
然後重新整理頁面。
可以篩選:
CSS
查看瀏覽器實際載入了哪些 CSS。
例如找到:
styles.css
點進去後可以確認:
Request URL
Status Code
如果是:
200
通常代表 CSS 有成功取得。
如果是:
404
代表瀏覽器正在找這支 CSS,但路徑不對或檔案不存在。

這時整條線就可以確認到:
SCSS
↓
成功編譯成 CSS
↓
Layout 有載入 CSS
↓
瀏覽器真的請求這支 CSS
這時問題可能已經不是「檔案沒有載入」,而是「CSS 規則沒有套用」。
最常見的其中一種情況就是 selector 沒有選到。
例如 HTML 是:
<div class="home-page">
<h1 class="page-title">首頁</h1>
</div>
但 CSS 寫成:
.home .page-title {
color: red;
}
HTML 根本沒有:
home
這個 class。
所以 CSS 雖然成功載入,也不會產生效果。
可以在瀏覽器:
F12
↓
Elements
選擇目前的 HTML 元素。
右邊通常會看到:
Styles
這裡可以確認:
這個元素目前吃到哪些 CSS?
例如:
.page-title {
color: blue;
}
如果樣式有出現但被畫掉:
color: blue;
可能代表它被另一條 CSS 覆蓋。
例如:
.page-title {
color: blue;
}
header .page-title {
color: red;
}
最後因為 CSS 權重或載入順序,實際顯示可能是紅色。

所以:
CSS 有載入
和:
CSS 有成功套用
也是兩件不同的事。
有時候:
SCSS 有改
CSS 有更新
Layout 路徑也正確
結果瀏覽器還是顯示舊樣式。
這時候有可能是瀏覽器快取。
可以先嘗試重新整理。
如果還是不對,在開發者工具開啟時,也可以暫時停用快取再重新載入。
不過我不會一開始就直接怪快取。
我的檢查順序通常還是:
先確認 SCSS
↓
確認 CSS
↓
確認 HTML 有載入
↓
確認 Network
↓
確認 selector
↓
最後再考慮 cache
不然很容易:
畫面沒變
↓
一直 Ctrl + F5
↓
其實只是自己根本沒把那支 SCSS 引進來
XD
如果今天遇到:
我明明改了 SCSS,為什麼畫面完全沒有改?
我不會再一直盯著 SCSS 重寫。
而是從頭確認:
1. 我改的是哪支 SCSS?
↓
2. 它有沒有被入口 SCSS 引入?
↓
3. compilerconfig.json 編譯的是不是這個入口?
↓
4. 編譯後 CSS 有沒有真的出現我的修改?
↓
5. _Layout.cshtml 或 View 載入的是不是這支 CSS?
↓
6. Network 有沒有成功載入?
↓
7. HTML 的 class 和 CSS selector 有沒有對上?
↓
8. Styles 裡是不是被其他 CSS 覆蓋?
↓
9. 最後再確認是不是快取
這樣就可以把「畫面沒變」拆成幾段:
SCSS 問題
編譯問題
CSS 路徑問題
瀏覽器載入問題
CSS selector 問題
CSS 權重問題
快取問題
而不是全部都叫做:
CSS 壞了
以前寫 React 時,也可能直接寫:
import './Home.scss';
所以會感覺:
Component
↓
import SCSS
↓
畫面有樣式
但其實瀏覽器最後依然不是直接理解 SCSS。
React 專案通常是由 Vite、Webpack 或其他前端工具鏈幫忙處理:
SCSS
↓
前端建置工具
↓
CSS
↓
瀏覽器
MVC 專案如果使用 Web Compiler,則可能是:
SCSS
↓
Web Compiler
↓
wwwroot/css/styles.css
↓
_Layout.cshtml
↓
瀏覽器
所以兩邊最後都一樣:
瀏覽器真正理解的是 CSS。
只是「誰幫我完成 SCSS → CSS」的工具和流程不同。
這次我主要問:
為什麼 SCSS 編譯成功,畫面還是不一定會改?
怎麼知道我的 Partial SCSS 有沒有真的被編譯進 CSS?
MVC 的 CSS 到底在哪裡被載入?
怎麼確認瀏覽器真的有載到這支 CSS?
CSS 有載入但沒有作用,又要從哪裡看?
AI 幫我把問題拆成:
SCSS
↓
編譯
↓
CSS
↓
HTML
↓
Browser
我再一段一段回專案確認。
這比單純問:
為什麼我的 CSS 沒作用?
好用很多。
因為至少我開始知道:
現在到底是哪一層有問題?
最重要的一件事:
瀏覽器不會直接吃我寫的 SCSS
完整流程其實是:
Partial SCSS
↓
入口 SCSS
↓
Compiler
↓
CSS
↓
_Layout.cshtml 或 View 載入
↓
瀏覽器取得 CSS
↓
Selector 套用到 HTML
↓
畫面才真的改變
所以:
編譯成功
只代表:
SCSS → CSS
這一段可能成功了。
並不代表後面的:
CSS → 頁面 → 瀏覽器
也一定正確。
而我一路找「CSS 到底在哪裡被載入」時,最後又碰到了一個新的檔案:
_Layout.cshtml
奇怪的是,我明明看的頁面是 Index.cshtml,Header、Sidebar、CSS、JavaScript 卻可能都在 _Layout.cshtml。
下一篇就來整理:
_Layout.cshtml到底是什麼?為什麼一個看起來只有幾行內容的Index.cshtml,最後可以組成完整頁面?