css一行点点点_如何通过一点点创意使CSS成为不可能

css一行点点点

by Facundo Corradini

由Facundo Corradini

If you ever used CSS sibling selectors, you know there’s only two. The + sibling combinator selects the first match that comes immediately after, and the ~ subsequent-sibling combinator matches all the ones that come after.But there’s no way to select what came before. Either parent selectors or previous siblings selectors are simply not a thing.

如果您曾经使用CSS兄弟选择器,那么您将知道只有两个。 +同级组合器会选择紧随其后的第一个匹配项,而~后同级组合器将匹配所有随后的匹配项,但是无法选择之前的匹配项。 父选择器或先前的兄弟选择器都不是问题。

I know you want it, you know I want it, but the harsh truth is that they don’t exist (and probably never will). There are a million posts about the whys. There are even proposals on how to implement them. But we are stuck in the unidirectional processing of CSS rules, most likely to protect us from our “lack of expertise” getting us stuck in re-flows and even infinite loops.

我知道您想要它,您知道我想要它,但残酷的事实是它们不存在(可能永远不会)。 有上百万个关于为什么的帖子。 甚至还有关于如何实施它们的建议。 但是我们被困在CSS规则的单向处理中,最有可能使我们免受“专业知识”的困扰,使我们陷入重排甚至无限循环中。

Luckily, as with most CSS limitations, we can fake it.

幸运的是,与大多数CSS限制一样, 我们可以伪造它

The first thing to consider is why we want previous siblings to begin with. Two cases come to mind:

首先要考虑的是为什么我们希望以前的兄弟姐妹开始。 我想到两种情况:

  1. We need to select all siblings of a certain element, and the ~ subsequent sibling combinator is only selecting the ones that come after.

    我们需要选择某个元素的所有同级,并且~后续同级组合器仅选择后面的同级。

  2. We need to select only siblings that came before

    我们只需要选择之前的兄弟姐妹

1.选择所有兄弟姐妹 (1. Selecting all siblings)

Sometimes we need to select both previous and next siblings. To do that, we can actually select the parent and use some tricks around it.

有时我们需要同时选择上一个和下一个兄弟。 为此,我们实际上可以选择父级,并使用一些技巧。

For instance, to select all spans in the following structure when we hover any of them, we could just use the child selector on the parent’s hover. We make sure to disable the pointer-events from the parent and reset it back on the children. So whatever action we want to happen will only fire when we enter the child and not the parent itself.

例如,当我们将任何一个跨度悬停时,要在以下结构中选择所有跨度,我们可以仅在父级悬停时使用子选择器。 我们确保从父级禁用pointer-events ,并在子级上重置它。 因此,无论我们想采取什么行动,只有在我们进入孩子而不是父母本身时才会触发。

If you need to select all siblings except the one being hovered, you can combine the previous technique with the :not selector to exclude it.

如果您需要选择所有的兄弟姐妹,除了一个是徘徊,你可以在以前的技术与合并:not选择将它排除在外。

A typical use case for this is menus:

一个典型的用例是菜单:

The code above will turn down the opacity of all <li> elements but the one being hovered.

上面的代码会拒绝所有的不透明度< LI> ELE 换货秒,但所述一个感徘徊。

Furthermore, you could use filters such as type and nth selectors to be extra precise on the siblings that you want to affect.

此外,可以使用类型和第n个选择器之类的过滤器来更精确地确定要影响的同级对象。

With some styling, it should work like this:

带有某些样式,它应该像这样工作:

Please note: If you’re gonna run the pointer-events:none approach, bear in mind it can mess with stacking (might allow you to select elements that are “below” in the stacking order). It also won’t work in IE10 and below, apart from the implication that you might need the pointer events for something else. So be extra careful when using it.

请注意 :如果您要运行pointer-events:none方法,请记住它可能会导致堆叠混乱(可能允许您选择堆叠顺序“以下”的元素)。 除了暗示您可能还需要指针事件以外,它在IE10及更低版本中也将不起作用。 因此,使用时要格外小心。

2.选择之前的内容 (2. Selecting what came before)

For this use case, we can reverse the order on the HTML, then sort it back in CSS, and use the ~ subsequent sibling combinator or + adjacent sibling selector. This way we’ll be selecting the next siblings, but it’ll look like we are selecting previous ones.

对于此用例,我们可以颠倒HTML上的顺序,然后在CSS中对其进行排序,然后使用~后续同级组合器或+相邻同级选择器。 这样,我们将选择下一个兄弟姐妹,但看起来就像我们在选择前一个兄弟姐妹。

There are multiple ways to do this. The simplest and probably oldest is changing the writing direction of our container:

有多种方法可以做到这一点。 最简单的方法,也许是最古老的方法是更改​​容器的书写方向:

If your elements need to display actual text, you can always reverse it back:

如果您的元素需要显示实际文本,则可以随时将其反向:

But that can get out of hand in many ways. Luckily the modern CSS toolbox makes it much simpler and safer. We can just use Flexbox on the container and reverse the order with flex-direction:row-reverse:

但这可以在许多方面失控。 幸运的是,现代CSS工具箱使它变得更加简单和安全。 我们可以在容器上使用Flexbox并使用flex-direction:row-reverse

The best thing about the Flexbox approach is that we don’t mess with the writing direction. We don’t need to reset the children, and everything is much more predictable.

Flexbox方法最好的一点是,我们不会弄乱编写方向。 我们不需要重置孩子,并且所有事情都可以预测。

使用“以前的兄弟姐妹”创建仅CSS的星级评分系统 (Using “previous siblings” to create a CSS-Only stars rating system)

Semantically, a rating system can be thought of as just a simple list of radio buttons with their corresponding labels. That comes in handy, as it will allow us to use the :checked pseudo-selector to modify the siblings.

从语义上讲,可以将评级系统视为单选按钮及其相应标签的简单列表。 这很方便,因为它将允许我们使用:checked伪选择器来修改兄弟姐妹。

So let’s start from there:

因此,让我们从那里开始:

As we discussed previously, elements are in reverse order to allow for a “previous sibling” selector. Notice we are using the unicode “white star” character (U+2606) to represent the empty stars.

如前所述,元素的顺序相反,以允许使用“先前的同级”选择器。 请注意,我们使用的是Unicode“白星”字符(U + 2606)来表示空星。

Let’s display them side by side, in the correct (reverse) order:

让我们以正确的(反向)顺序并排显示它们:

Now hide the radio buttons themselves, no one wants to see that:

现在隐藏单选按钮本身,没有人希望看到:

And apply some styling to the star characters:

并对星形字符应用一些样式:

The only truly important line there is the position:relative. It will allow us to absolute position a filled star (U+2605) pseudo element on top of it, which will be initially hidden.

唯一真正重要的一行是position:relative 。 这将使我们能够将实心星(U + 2605)伪元素绝对定位在其顶部,该元素最初将被隐藏。

When we hover over a star, the filled star pseudo element should become visible for it and all previous siblings.

当我们将鼠标悬停在恒星上方时,填充的恒星伪元素对于它和所有先前的同级物应该是可见的。

Same thing for the selected rating, by matching all labels that come before the checked radio button:

通过匹配选中的单选按钮之前的所有标签,可以为选定的评分相同:

Remember that using the !important flag is exactly the opposite of a good practice. I do so here as there’s no other way to achieve the added functionality discussed in the next section without it.

请记住 ,使用!important标志优良做法完全相反 。 我之所以这样做,是因为没有其他方法就无法实现下一节中讨论的附加功能。

Last but not least, we need to “remember” the current rating, just in case the user wants to change it. For instance, if they had selected five stars, and for whatever reason want to change it to four, we should display stars 1 to 4 as filled and the fifth as semi-transparent when hovering over the fourth.

最后但并非最不重要的一点是,我们需要“记住”当前评分,以防用户想要更改它。 例如,如果他们选择了五颗星,并且出于任何原因想要将其更改为四颗,则当悬停在第四颗星上时,我们应将其显示为填充的星1至4颗,将第五颗显示为半透明。

That can be achieved by changing the opacity of the previous siblings of the checked input when hovering over the container:

将鼠标悬停在容器上时,可以通过更改已检查输入的先前同级对象的不透明度来实现:

That’s also why we needed the opacity:1 !important in the initial hovering declaration. Otherwise this last rule would have won the specificity contest and applied a semi-transparent fill to everything.

这就是为什么我们在初始悬停声明中需要opacity:1 !important的原因。 否则,这最后一条规则将赢得特异性竞赛,并对所有事物应用半透明填充。

And there we have it, a cross-browser, fully functional CSS-only stars rating system using “previous siblings” selectors.

在那里,我们有了一个跨浏览器,功能齐全的仅CSS的星级评分系统,使用“以前的兄弟姐妹”选择器。

As you can see, just because “it’s impossible” doesn’t mean you shouldn’t try. Programming is about pushing the limits. So whenever you hit the wall, just push a little harder. Or I guess finding your way around it might be a better analogy?… anyway, you know what I mean. Keep on hacking!

如您所见,仅仅因为“不可能”并不意味着您不应该尝试。 编程是为了突破极限。 因此,每当碰到墙壁时,都需要加一点力气。 还是我想找到一种解决方法可能是更好的比喻?…无论如何,您知道我的意思。 继续骇客!

关于可访问性的说明 (A note on accessibility)

The previous snippet is a simplification in order to make it easy to understand. It is not something I would recommend to use on production due to many accessibility limitations.

上一个代码段是一个简化版本,以使其易于理解。 这是不是我会建议在生产使用中因许多辅助功能的局限性。

In order to make the snippet a little more accessible, first thing would be to hide the radio buttons with pretty much any technique other than display:none to make them focusable. We should also add some focus ring on the whole stars snippet when any element inside is focused, via the pseudo-selector :focus-within.

为了使代码片段更易于访问,第一件事是使用display:none以外的几乎任何其他技术隐藏单选按钮display:none使其可聚焦。 当内部的任何元素都被聚焦时,我们还应该通过伪选择器:focus-within在整个星星片段上添加聚焦环。

The identical “☆” labels makes no sense for screen readers, so best approach will be to have a an> inside the label with “n Stars” text, that will be hidden from sighted users .

对于屏幕阅读器来说,相同的“☆”标签毫无意义,因此最好的方法是在标签内放置一个带有“ n星”文字的 an>,该标签将对视力不佳的用户隐藏。

Also the reverse HTML source + display:row-reverse approach makes keyboard rating awkward, as it doesn’t get reversed back. Flexbox and keyboard accessibility is quite a messy topic, but closest thing to a solution for that one is adding aria-flowtotag to each element, which at least fixes the issue for some screen readers + browser combinations.

反向HTML源代码+ display:row-reverse方法也使键盘评级很尴尬,因为它不会反向返回。 Flexbox和键盘的可访问性是一个很杂乱的话题,但是,与该解决方案最接近的解决方案是在每个元素上添加aria-flowto标签,这至少可以解决某些屏幕阅读器+浏览器组合的问题。

For a more accessible snippet (using an alternative technique of modifying next siblings to look empty instead of trying to asses previous ones) check Patrick Cole’s, as we discussed in the answers below.

对于更易于访问的代码段(使用另一种方法来修改下一个兄弟姐妹以显示为空而不是尝试评估之前的兄弟姐妹),请查看Patrick Cole的内容,如我们在下面的答案中所述。

翻译自: https://www.freecodecamp.org/news/how-to-make-the-impossible-possible-in-css-with-a-little-creativity-bd96bb42b29d/

css一行点点点

你可能感兴趣的:(css,java,web,js,html,ViewUI)