Skip to content

Conversation

@adamwathan
Copy link
Member

@adamwathan adamwathan commented Jul 12, 2019

This PR adds new first-child and last-child variants to the framework, but disabled by default for all core plugins.

These allow you to apply a utility to an element only when it is the first child or last child of its parent. Very useful for things like "put a border between all of these items that are generated in a loop" for example:

<ul>
  <li v-for="item in items" class="border-t first-child:border-t-0">{{ item }}</li>
</ul>

Something worth emphasizing is that these variants apply to the child element itself, not to the children of the element with the utility. This is consistent with how other pseudo-class variants in Tailwind work, and how the :first/last-child pseudo selectors work in CSS.

Said again in code:

<!-- This is *not* how the plugin is meant to be used -->
<ul class="first-child:border-t-0">
  <li v-for="item in items" class="border-t">{{ item }}</li>
</ul>

<!-- The utilities should be used on the child itself, not the parent -->
<ul>
  <li v-for="item in items" class="border-t first-child:border-t-0">{{ item }}</li>
</ul>

@MichaelDeBoey
Copy link
Contributor

If I understand correctly, this won’t have any hover:first-child:border-t-0 right? 🤔

If I would want that, I need to create a custom plugin that looks more like the group-hover plugin I guess?

@adamwathan
Copy link
Member Author

Yeah variants (other than responsive which is sort of a special case) don't "stack" in Tailwind, so you'd have to create a new variant that combined the two states. Maybe one day we can come up with a good solution for stacking but I don't have any really great ideas yet 🤔

@pxwee5
Copy link
Contributor

pxwee5 commented Jul 16, 2019

This is great. However, is there not a way to shorten the class names? first-child:border-b-1 is a very long class name IMO
For e.g. first:border-b-1 or fc:border-b-1?

@adamwathan
Copy link
Member Author

Yeah think just going to go with first: for the reasons you mentioned.

@rebolyte
Copy link

@pxwee5 Agreed. To me the name first-child: implies that it should go on the parent, where just first: makes sense on child elements.

@adamwathan
Copy link
Member Author

@rebolyte Lot of people seem to interpret it that way which I find a bit surprising to be honest, since CSS works the same way. li:first-child means "styles for this li when it is the first child", not "target the first child of this li".

With Tailwind's variant prefixes I find it useful to read them like guard conditions.

hover:bg-blue translates to "if this element is hovered, make the background blue".
first-child:border-t-0 would then translated to "if this element is the first child, remove the top border".

Variants are always about querying some sort of state, not about traversing the document structure.

@benface
Copy link
Contributor

benface commented Jul 16, 2019

I think what makes this one a bit more confusing than hover and other state variants is that there is no real reason to use it when authoring a static HTML document, since you can easily see when an element is the first child or the last child of its parent, and apply whatever utilities you need to that element directly. Basically you would only need first: or last: when working with a template engine that generates multiple elements from the same template / classes. Whereas first-child: / last-child: variants that were meant for the parent element to affect their first/last child would make more sense in a static HTML document (to eliminate some duplication), but would perhaps not be very useful with a template engine.

@adamwathan
Copy link
Member Author

Changed to first/last.

@adamwathan adamwathan merged commit b11db0e into master Jul 20, 2019
@adamwathan adamwathan deleted the first-last-child-variants branch July 20, 2019 15:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants