Repository: tailwindlabs/tailwindcss (TypeScript)
Task type: Feature

Issue:
State Variants Priority Order
## Foreword ##
People are (or at least, I am) increasingly excited about the possibility of having everything they need out of the box thanks to Tailwind, and state variants are a vital part of building user interfaces.
Tailwind already supports a bunch of them, but new ones are always proposed and discussed (see #136) and, as time goes on, they may get introduced as well.

## Purpose ##
There is a problem though: since Tailwind does not rely on `!important` 
 rules to override styles, the output order of the state variants becomes crucially important.
It's true: users may tailor their code by implementing priorities by themselves and fit their needs!
Good defaults, however, could save a lot of headaches and work.

That's what this thread is for: discuss better state variants priorities.



Discussion:
## Hover vs. Focus ##
Currently, hover has a higher priority than focus. However, as discussed in the PR #379, this choice has his pros and cons.
As it is now, buttons have huge benefits, whilst inputs may lack consistency.

Are you relying on or fighting against this order?



Solution patch:
diff --git a/src/lib/substituteVariantsAtRules.js b/src/lib/substituteVariantsAtRules.js
--- a/src/lib/substituteVariantsAtRules.js
+++ b/src/lib/substituteVariantsAtRules.js
@@ -48,7 +48,7 @@ export default function(config) {
 
       atRule.before(atRule.clone().nodes)
 
-      _.forEach(['focus', 'hover', 'group-hover'], variant => {
+      _.forEach(['group-hover', 'hover', 'focus'], variant => {
         if (variants.includes(variant)) {
           variantGenerators[variant](atRule, unwrappedConfig)
         }


Test patch:
diff --git a/__tests__/variantsAtRule.test.js b/__tests__/variantsAtRule.test.js
--- a/__tests__/variantsAtRule.test.js
+++ b/__tests__/variantsAtRule.test.js
@@ -69,9 +69,9 @@ test('it can generate group-hover variants', () => {
   })
 })
 
-test('it can generate hover and focus variants', () => {
+test('it can generate all variants', () => {
   const input = `
-    @variants hover, focus {
+    @variants hover, focus, group-hover {
       .banana { color: yellow; }
       .chocolate { color: brown; }
     }
@@ -80,10 +80,12 @@ test('it can generate hover and focus variants', () => {
   const output = `
       .banana { color: yellow; }
       .chocolate { color: brown; }
-      .focus\\:banana:focus { color: yellow; }
-      .focus\\:chocolate:focus { color: brown; }
+      .group:hover .group-hover\\:banana { color: yellow; }
+      .group:hover .group-hover\\:chocolate { color: brown; }
       .hover\\:banana:hover { color: yellow; }
       .hover\\:chocolate:hover { color: brown; }
+      .focus\\:banana:focus { color: yellow; }
+      .focus\\:chocolate:focus { color: brown; }
   `
 
   return run(input).then(result => {
@@ -104,10 +106,10 @@ test('it wraps the output in a responsive at-rule if responsive is included as a
     @responsive {
       .banana { color: yellow; }
       .chocolate { color: brown; }
-      .focus\\:banana:focus { color: yellow; }
-      .focus\\:chocolate:focus { color: brown; }
       .hover\\:banana:hover { color: yellow; }
       .hover\\:chocolate:hover { color: brown; }
+      .focus\\:banana:focus { color: yellow; }
+      .focus\\:chocolate:focus { color: brown; }
     }
   `