Add new pseudo classes (after, nth-child, etc...)

Hello,

Currently, there is no way to apply properly common web pseudo-classes.

Some tried by using manipulators : x.com

Other used Harmony library to overwrite the UITK code and enforce their usage : UI Toolkit Component | GUI Tools | Unity Asset Store

But those pseudo classes are used in web for years ; they should be accessible inside UI TK too! I think about :first-child, :last-child and :nth-child, because they are very common and it seems they aren’t planned in the roadmap.

There also are ::before and ::after. But, eventhough I miss those, I think they are at lower priority.

If you could add those pseudo classes or, at least, expose the pseudo class API a bit more to create ours, that should be really a time saver!

Thank you

12 Likes

Hi DarkRewar,

Could you please give me one or some examples of where you’d find useful to have :first-child, :last-child and :nth-child? Would having the gap property solve some of the problems or do you see them as being complementary?

I made two examples to illustrate my request on codepen. Both cases are not possible with gap.
The first is using :nth-child(even) and :nth-child(odd) to create automatically alternance between rows (it’s pure CSS, so we will not need any custom control or manipulator).
The second one is using :last-child, :not() and ::after pseudo-classes to manage a breadcrump in pure CSS too.

Codepen : https://codepen.io/Rewar/pen/BaqbQVE

9036403--1247662--upload_2023-5-25_10-51-20.png

4 Likes

That’s a good use case. Also, :first-child, :nth-child(*), :last-child could be used, for example, in racing games for a sheet with the results of the race after finish tournament. As a player, you need to finish in the top three. The winner would receive a gold medal [:first-child], the second racer would receive a silver medal [:nth-child(2)] and the third racer would receive a bronze medal [:nth-child(3) with border-bottom]. The last racer would not advance to the next tournament [:last-child with red background]. That’s another example where these pseudo-elemets would be very useful. And it could be styled without code intervention on the C# side. Regardless of the outcome of the race, the styling would still be the same, according to the order of the racers.

1 Like

Thank you folks, that’s very useful, we’ll add that request to the backlog for future prioritization.

4 Likes

I found a way to enforce the :first-child pseudo-class, but it is tricky and not really the better way.

I used Harmony to patch the UnityEngine.UIElements.StyleSheets.StyleSelectorHelper.MatchesSelector method and execute a method after its call. Then, I read every parts of the selector and check if it’s a PseudoClass type and a first-child value. Then I update the result by setting the match success to true.

But this is using reflection and Harmony, still I can’t build in IL2CPP and it slows down the UI Builder and any interaction in the editor.

Throwing my two cents in on first/last/nth-child selectors, though if gap were supported and easier to add, that’d solve enough of my needs to shut me up. @benoitd_unity is there an issue we can throw votes on or follow for updates?

1 Like

+1

+1 for :first-child, :last-child and :nth-child

1 Like

+1

+1

I find myself wishing these existed increasingly often, the more I try and use uss over hardcoding all of my styles. Due to the lack of them, I can’t take advantage of uss as often as I would like/should.

1 Like

+1.
Without having access to CSS standard features like display: grid or gap it becomes very difficult to do a simple spacing between elements in a flex list.

At least with something like :not() or :first-child/:last-child or any of the other basic pseudo classes this would be easily implemented.

As it is right now, such a simple task like consistent spacing between items becomes difficult for no reason.

4 Likes
  • 1 for this. Having this selector would eliminate a lot of custom code that was being added to make sure we have the proper styling for children elements.

Example of one thing that this would make super easy is Button Groups styling. Imagine you have a Button Group custom control that has Buttons as children. You want the left most Button to have a border radius on the left side, but not the right side. The last Button has a border radius on the right side, but none on the left side. The ones in the middle have no border radius at all.

You can still do this, but when you have multiple types of custom controls you want to do it for and have to write extra C# code to check the order the child elements is in the hierarchy it starts to become a burden that shouldn’t be there for devs.

Think of Bootstraps Button Group examples at the link below.

2 Likes

We are nearly late 2024 and Unity 6 still does not have any kind of nth-child or else.
If you are looking into something similar, I made a Control that uses somes manipulators to automatically add first-child, last-child, even, odd and some others in my UITK framework : leaframe/Runtime/Controls/Layouts/Container.cs at master · DarkRewar/leaframe · GitHub

Any news on this topic? yes, no, maybe?

I don’t know, can you repeat the question?

Joke aside, I used my own manipulator to achieve this because it still isn’t even planned on the roadmap…

I saw your code, not a fan of the manipulator aproach. I would rather add behavior on demand via extension methods.
I’ll be back with my solution when I have something more or less acceptable.

I would like to know which solution you found. Because after many investigations, the manipulator solution was the only proper solution I found, because it works on IL2CPP build and can be safely used from USS (with .first-child, .last-child, .even-child and odd-child classname selectors).

1 Like

Here’s my first attempt: gist
Gap probably breaks if flex-direction changes