[英]Applying an effect to multiple pseudo classes at once in tailwind
我正在尋找一個很好的速記來將相同的效果應用於 tailwind 中的多個偽類。
例如,我可能想對 div 上的 :hover 和 :focus 狀態應用藍色背景。
目前我必須寫下以下內容:
<div className="hover:bg-blue focus:bg-blue>Text<div>
或者,我可以使用 apply 來構建自定義 class,如下所示:
.hover-focus-bg-blue {
@apply hover:bg-blue focus:bg-blue
}
但是,當我必須應用復雜狀態時,這些都不是很好的選擇(在我當前的項目中,我需要在一個元素上覆蓋 11 種狀態(rest/hover/active/focus/focus-visible/focus-visible && hover 等)。
apply 方法僅在多次使用時才保存代碼。
我想看到的是這樣的:
<div className="[hover, focus]:bg-blue">Text</div>
有誰知道這樣的語法? 到處都找不到。
這是一個經常被問到的問題。 主要是關於將類分組為一個分組語法(例如, hover:(bg-red-500 border-2)
。
這是我在搜索此問題的解決方案后收到的答案。 總之,這個功能暫時不存在。 盡管這個答案指的是將實用程序分組到一個選擇器中,但相同的邏輯應該適用於偽選擇器的分組:
Tailwind 的維護者確實曾經考慮過這個功能,但最終決定暫時擱置它。 看到這個 Twitter 線程: https://twitter.com/adamwathan/status/1461519820411789314
因此,正如您從答案和 Twitter 提要中看到的那樣,它目前處於暫停狀態。 在 Twitter 線程中,開發人員正在測試此功能的性能,與使用單獨的實用程序相比,此功能在其當前 state 重復 CSS:
因此,我們進行了一項測試,將每個 Tailwind UI 模板(超過 500 個文件)轉換為使用分組語法,以查看在為 HTML 提供服務時可以節省多少帶寬分組。
當您考慮它時,這是有道理的,因為使用分組語法(如
focus:(font-bold,underline)
)會導致文檔中的重復符號更少,因為現在有更多唯一的 class 名稱。
使用非分組語法,
focus:font-bold
的每個實例都可以被壓縮並替換為一個短占位符(比如 %)。 使用分組語法,focus:font-bold
和focus:(font-bold,underline)
不能被壓縮掉,因為它們不再相同。 Plot twist: 壓縮后文件變大了,不是變小了!
所以這里的要點是,雖然分組語法在編寫時看起來代碼更少,但它實際上在生產中創建了更大的 CSS 文件和更大的 HTML 文件,使其成為一個非常黑白的性能反模式。
雖然寫起來更好,而且性能成本不是很大,所以我們仍然有機會進一步開發它,只是為了喜歡它的人的開發人員體驗。 但不可否認的是,對於鼓勵任何對績效不利的事情猶豫不決。
我最近在另一個關於分組類的問題中提供了一個答案,但你的問題有點不同,所以這是對以前的 function 的改進版本:
const pseudoJoin = (selectors, str) => {
let result = "";
selectors.forEach(selector=> result+=selector+":"+str.split(" ").join(" "+selector+":")+" ")
return result;
}
現在您可以在任何地方調用它,例如:
<div className=`${pseudoJoin(['hover','focus'],"classes you want on hover & focus")} some more classes here ${pseudoJoin(['focus'],"classes when focused")}`>Hello World!</div>
或者當您使用classnames
框架時:
<div className={ classnames(
pseudoJoin(['hover','focused'], "classes you want on hover & focused"),
"Other classes here",
pseudoJoin(['focused'], "classes when focused")
)}>Hello World!</div>
為了進一步縮短它,您可以用更短的名稱替換pseudoJoin
,因為我想不出更好的名稱。
我之前的回答是輕量級、快速的 function,但這個並不注重性能,而是考慮了易用性。
const pseudoJoin = (str) => {
let result= [];
let storedvar;
str=str.split(" ");
str.forEach(function(s,i){
if((/\:\(/).test(s)) storedvar=i;
if(!storedvar) result.push(s);
if(s.endsWith(")")){
result.push(str.slice(storedvar,i+1).join(" "))
storedvar=null;
}
})
str=[]
result.forEach(function(s,i){
if((/\w\:/).test(s)){
storedvar = s.split(/\:(.*)/s);
if(s.endsWith(")")){
storedvar[1].slice(1,-1).split(" ").forEach(function(t){
storedvar[0].split("+").forEach(function(x){str.push(x+":"+t)})
})
} else {
storedvar[0].split("+").forEach(function(x){
str.push(x+":"+storedvar[1])
})
}
} else {
str.push(s)
}
})
return str.join(" ");
}
以下是如何使用新的 function 的示例:
pseudoJoin("hover:text-black hover+focus+active:(bg-white margin-[3.2rem] underline) before+after:content-[Hello_\+_I_am_groot] sm:hidden"));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.