简体   繁体   English

在顺风中一次将效果应用于多个伪类

[英]Applying an effect to multiple pseudo classes at once in tailwind

I am looking for a good shorthand to apply the same effect to multiple pseudo classes in tailwind.我正在寻找一个很好的速记来将相同的效果应用于 tailwind 中的多个伪类。

For example, I may want to apply a blue background to both:hover and:focus states on a div.例如,我可能想对 div 上的 :hover 和 :focus 状态应用蓝色背景。

Currently I'd have to write the following:目前我必须写下以下内容:

<div className="hover:bg-blue focus:bg-blue>Text<div>

OR, i could use apply to build out a custom class like this:或者,我可以使用 apply 来构建自定义 class,如下所示:

.hover-focus-bg-blue {
  @apply hover:bg-blue focus:bg-blue
}

But neither of these are great options when i have to apply complex states (in my current project I need to cover 11 states on one element (rest/hover/active/focus/focus-visible/focus-visible && hover etc).但是,当我必须应用复杂状态时,这些都不是很好的选择(在我当前的项目中,我需要在一个元素上覆盖 11 种状态(rest/hover/active/focus/focus-visible/focus-visible && hover 等)。

The apply method only saves code if there are multiple uses of it. apply 方法仅在多次使用时才保存代码。

What I would like to see is something like:我想看到的是这样的:

<div className="[hover, focus]:bg-blue">Text</div>

Does anyone know of some syntax like that?有谁知道这样的语法? Can't find it anywhere.到处都找不到。

This is a question that is asked frequently.这是一个经常被问到的问题。 Mostly it's about grouping classes into one grouped syntax (for example, hover:(bg-red-500 border-2) .主要是关于将类分组为一个分组语法(例如, hover:(bg-red-500 border-2)

This is the answer I received after searching for a solution to this question.这是我在搜索此问题的解决方案后收到的答案。 In short, this functionality doesn't exist for now.总之,这个功能暂时不存在。 Even though this answer refers to the grouping of utilities into one selector, the same logic should apply to the grouping of pseudo-selectors:尽管这个答案指的是将实用程序分组到一个选择器中,但相同的逻辑应该适用于伪选择器的分组:

Wongjn的回答

The Tailwind maintainers did look at this feature at one point but ultimately decided to put it on hold for now. Tailwind 的维护者确实曾经考虑过这个功能,但最终决定暂时搁置它。 See this Twitter thread: https://twitter.com/adamwathan/status/1461519820411789314看到这个 Twitter 线程: https://twitter.com/adamwathan/status/1461519820411789314

So, as you can see from the answer and the Twitter feed, it's currently on hold.因此,正如您从答案和 Twitter 提要中看到的那样,它目前处于暂停状态。 In the Twitter thread, the developers were testing this feature regarding performance, and it looks like this feature, at its current state duplicates CSS compared to using individual utilities:在 Twitter 线程中,开发人员正在测试此功能的性能,与使用单独的实用程序相比,此功能在其当前 state 重复 CSS:

So we did a test where we converted every single Tailwind UI template (over 500 files) to use the grouped syntax to see how much bandwidth grouping would save you when serving HTML.因此,我们进行了一项测试,将每个 Tailwind UI 模板(超过 500 个文件)转换为使用分组语法,以查看在为 HTML 提供服务时可以节省多少带宽分组。

This makes sense when you think about it, because using the grouped syntax (like focus:(font-bold,underline) ) leads to fewer repeated symbols in the document, because there are now more unique class names.当您考虑它时,这是有道理的,因为使用分组语法(如focus:(font-bold,underline) )会导致文档中的重复符号更少,因为现在有更多唯一的 class 名称。

Using the non-grouped syntax, every instance of focus:font-bold can be compressed out and replaced with a short placeholder (say %).使用非分组语法, focus:font-bold的每个实例都可以被压缩并替换为一个短占位符(比如 %)。 Using grouped syntax, focus:font-bold and focus:(font-bold,underline) can't be compressed out, because they are no longer the same.使用分组语法, focus:font-boldfocus:(font-bold,underline)不能被压缩掉,因为它们不再相同。 Plot twist: After compression, the files are actually bigger , not smaller! Plot twist: 压缩后文件变大了,不是变小了!

Bottom line:底线:

So the takeaway here is that although the grouped syntax looks like less code when you're authoring it, it actually creates both a bigger CSS file and a bigger HTML file in production, making it a very black and white performance anti-pattern.所以这里的要点是,虽然分组语法在编写时看起来代码更少,但它实际上在生产中创建了更大的 CSS 文件更大的 HTML 文件,使其成为一个非常黑白的性能反模式。

It's nicer to write though, and the performance cost isn't a huge one, so still a chance we develop it further just for the developer experience for the people who like it.虽然写起来更好,而且性能成本不是很大,所以我们仍然有机会进一步开发它,只是为了喜欢它的人的开发人员体验。 But admittedly hesitant to encourage anything that's bad for performance.但不可否认的是,对于鼓励任何对绩效不利的事情犹豫不决。

I recently provided an answer in another question for grouping classes here but your question is a bit different so here's an improved version to the previous function:我最近在另一个关于分组类问题中提供了一个答案,但你的问题有点不同,所以这是对以前的 function 的改进版本:

const pseudoJoin = (selectors, str) => {
  let result = "";
  selectors.forEach(selector=> result+=selector+":"+str.split(" ").join(" "+selector+":")+" ")
  return result;
}

Now you can call it anywhere like:现在您可以在任何地方调用它,例如:

<div className=`${pseudoJoin(['hover','focus'],"classes you want on hover & focus")} some more classes here ${pseudoJoin(['focus'],"classes when focused")}`>Hello World!</div>

Or when you are using classnames framework:或者当您使用classnames框架时:

<div className={ classnames(
   pseudoJoin(['hover','focused'], "classes you want on hover & focused"),
   "Other classes here",
   pseudoJoin(['focused'], "classes when focused")
)}>Hello World!</div>

For making it shorter even further, you can replace pseudoJoin with a shorter name because I couldn't think of a better name.为了进一步缩短它,您可以用更短的名称替换pseudoJoin ,因为我想不出更好的名称。

My previous answer was a lightweight, fast function, but this one doesn't focus on perfomance but rather accounts for ease.我之前的回答是轻量级、快速的 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(" ");
}

Here's example of how to use the new function:以下是如何使用新的 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM