[HN Gopher] Show HN: CSS Speedrun - A small game to test and imp...
       ___________________________________________________________________
        
       Show HN: CSS Speedrun - A small game to test and improve your CSS
       knowledge
        
       Author : Vincenius
       Score  : 195 points
       Date   : 2022-01-17 08:13 UTC (14 hours ago)
        
 (HTM) web link (css-speedrun.netlify.app)
 (TXT) w3m dump (css-speedrun.netlify.app)
        
       | Zekio wrote:
       | More fun than I expected, though I seem to have forgotten how IDs
       | are a thing you can target, everything is classes these days, so
       | only got a time of 10:28 due to spending minutes writing an
       | insane selector rather than ID, ID
        
       | sam_goody wrote:
       | Took me 8 minutes, but I felt that my answers for some were sub-
       | optimal.
       | 
       | It would be good if there was a way I could have seen other
       | users' answers, so I could learn new tricks.
        
         | derimagia wrote:
         | I agree, although there are hint links on each answer which
         | generally give you the selector you are "intended" to use
        
       | mrjay42 wrote:
       | I solved level 4 using is() But I am sure there's a better way
       | with the any of the attribute selectors
       | (https://developer.mozilla.org/en-
       | US/docs/Web/CSS/Attribute_s...). But I did not find how to do it
       | :'(
        
         | 411111111111111 wrote:
         | thats strange, i could just use i think `div[data-item]` and it
         | worked for me
        
           | mrjay42 wrote:
           | Oooh that's so nice! Thanks! I was trying to select stuff
           | using span[data-item*="foobar"] Or something of the
           | sort...but it wasn't working, so I just ended up writing a
           | is() selector ^^
        
       | mcv wrote:
       | 7:22, but I needed a lot of hints. And many of my selectors were
       | rather arbitrary lists of unconnected selectors. I feel like
       | there should be better answers than the ones I gave.
        
         | dotancohen wrote:
         | Did you look at the hints? I learned a bit from them.
        
       | 414owen wrote:
       | Huh, I wrote a very similar game a while ago. Select elements
       | with CSS selectors to get to the next level: https://select.pink/
       | 
       | Mine displays the elements as nested blocks, instead of printing
       | a tree.
        
         | naseemali925 wrote:
         | Thanks for sharing, learnt a few more CSS selectors.
        
         | 414owen wrote:
         | Thanks :)
         | 
         | I actually posted https://select.pink/ to HN ages ago, but it
         | died in `new`: https://news.ycombinator.com/item?id=24959045
         | 
         | OP's game has some nice features. The timing is neat, and to be
         | honest I didn't even consider using the source as the
         | visualization.
        
         | dotancohen wrote:
         | This is terrific! Do note that IDs are document unique. I found
         | a duplicate id on the `#pan.cake` exercise.
        
         | fgeiger wrote:
         | Wow, nice. I like this even better then the OP. In particular
         | how the levels naturally progress and how the game actively
         | teaches concepts.
        
         | aurbano wrote:
         | Awesome stuff! I learned a few new selectors, thanks :)
        
       | [deleted]
        
       | iheredia wrote:
       | * Spoiler *
       | 
       | The use of `:not` is way more powerful that I usually remember.
       | For example, the second exercise asks to select all the <p>
       | except the one with class="foo"                 <div>
       | <p></p>         <p class="foo"></p>         <p></p>
       | <p></p>       </div>
       | 
       | This can be done with                 p:not(.foo)
       | 
       | But also by selecting every thing that we don't want and then
       | negating that.                 :not(div, .foo)
        
         | gildas wrote:
         | However, note that doc page on MDN [1] warns you it may not
         | work in all browers.
         | 
         | > Using two selectors at the same time is not yet supported in
         | all browsers. Example: :not(.foo, .bar). For wider support you
         | could use, :not(.foo):not(.bar)
         | 
         | [1] https://developer.mozilla.org/en-US/docs/Web/CSS/:not
        
       | chrismorgan wrote:
       | Minor quibble: level 6's code uses </input>, which is invalid in
       | HTML syntax (though harmless): <input> is a void element, meaning
       | it can't have any children and has no end tag.
       | 
       | (You could write <input/>, the old XML syntax for self-closing
       | tags, but I strongly recommend against doing that because it
       | teaches a wrong mental model: that trailing slash is permitted in
       | HTML syntax on void elements for XHTML compatibility but does
       | _not_ close an element: it's just ignored.)
        
         | jacobmischka wrote:
         | Long live XHTML syntax for self-closing tags!
        
         | DaiPlusPlus wrote:
         | > I strongly recommend against doing that because it teaches a
         | wrong mental model
         | 
         | What's wrong with using XML as the underlying mental-model for
         | HTML5 (HTML "Living Standard", etc)? HTML still supports XHTML
         | and (to my knowledge) the only appreciable difference between
         | HTML and XHTML is the requirement that the HTML tag soup be a
         | well-formed XML document. That's it. XHTML is still valid HTML,
         | and XML's model is simple and easy to understand and covers
         | 100% of HTML's use-cases.
         | 
         | The difference between XHTML today vs. back in 2005 was that
         | the W3C grossly underestimated the extent at which modern
         | tooling will continue to generate invalid HTML markup (let
         | alone any truly semantic HTML markup either), so web-browsers
         | and scrapers needed to be more forgiving in their input
         | processing and also standardise how they interpreted invalid
         | HTML. None of that precludes us from writing software to a
         | higher standard: software which generates valid XHTML which
         | allows HTML to be handled by existing XML-processing
         | infrastructure (and even serialized to JSON if you're crazy).
         | What's "wrong" about any of that?
        
         | Vincenius wrote:
         | Good point - fixed it :)
        
       | codeptualize wrote:
       | That was honestly quite fun. I did 08:04:7
        
         | dotancohen wrote:
         | I agree, even as a backend dev I had a lot more fun with this
         | than I expected. 08:19:6, just slightly behind you.
        
       | nayuki wrote:
       | I used the child combinator (>) and adjacent sibling combinator
       | (+) a lot. I think these aren't used much in real-world code?
        
         | throwaddzuzxd wrote:
         | I personally use them a lot. `+` is very useful to create
         | separators, e.g.:                   p + p {           border-
         | top: 1px;         }
         | 
         | I also like to use `>` as much as possible instead of the
         | implicit ` ` child selector, I find it more robust and less
         | surprising.
         | 
         | I rarely use `~` though, but it has its uses.
        
       | tiffanyh wrote:
       | Love the project.
       | 
       | Wish it had the answer as well, not just hint.
        
         | soperj wrote:
         | Let me know which ones you want answers for and I can put them
         | in.
        
           | soperj wrote:
           | Actually, here:
           | 
           | 0. li:first-child
           | 
           | 1. p:not(.foo)
           | 
           | 2. li:nth-child(2n+3)
           | 
           | 3. div > *
           | 
           | 4. span[data-item]
           | 
           | 5. p ~ span
           | 
           | 6. form > *:enabled
           | 
           | 7. #one, #two, #five, #six, #nine
           | 
           | 8. a + span
           | 
           | 9. #foo > .foo
           | 
           | 10. div > div > span + code:not(.foo)
        
       | Nadya wrote:
       | 4:22 - I got stuck on the ID one because I felt like I was meant
       | to do something than select each one individually. I also got
       | stuck on :enabled and ended up writing something dumb in
       | retrospect. Some of my selectors were quite hacky in the name of
       | speed though.
       | 
       | It would have been nice to see what the intended solutions after
       | because otherwise I have no way of finding out that using
       | :enabled was the intended way and not input:not(disabled),
       | button:not(disabled). Realized after I could have used an :is
       | there but I don't use :is often in work due to browser support
       | for IE so it didn't cross my mind at the time. It would also be
       | nice to see that #one, #three, #five, #nine (or whatever the ID's
       | where for that puzzle) was indeed the "intended" answer as a kind
       | of trick question.
       | 
       | Without reading HN I would not have learned I was meant to use
       | :enabled.
        
         | divbzero wrote:
         | 2:54 for me. Curious to hear other first run times.
         | 
         | I too was using :not(:disabled) and learned :enabled only by
         | reading the parent comment.
        
       | woolion wrote:
       | Nice project!
       | 
       | It feels like it is missing ways to help you get to understand
       | things on your own, so a bit more like a test than a real game.
       | Maybe a codegolf scoring (number of characters) and/or semantic
       | scoring (number of atomic expressions used) would help?
       | 
       | As somebody who's doing frontend excessively rarely, it would
       | feel more rewarding to see it compared to some good practices
       | answers. Maybe store the results so you could display the most
       | frequent answers in a future iteration?
       | 
       | Took 16 minutes, trying to understand more than to speedrun. Btw,
       | link of hint 10 is broken (there's an extraneous comma).
       | 
       | The dynamic selection dots are quite neatly done. I found it
       | quite fun and it seems like there are many ways to add
       | interesting features!
        
         | youssefabdelm wrote:
         | I agree on the test thing. Would've been helpful for the
         | creator (if they actually wanted to create something that would
         | teach people who are new to it) to review educational
         | techniques employed by people such as Michel Thomas (https://ww
         | w.youtube.com/watch?v=W0fDO4IuO-M&ab_channel=Audio...),
         | programmed instruction (behavior analysis), and transfer of
         | learning.
        
           | 411111111111111 wrote:
           | i have to disagree strongly on this. on each challenge you
           | get a hint on the bottom which links you to the documentation
           | of the selector you've gotta use
           | 
           | it was the first time for me using elem ~ elem and elem +
           | elem selectors for example
        
       | TomAnthony wrote:
       | This was fun. :)
       | 
       | I feel like there should be another scoring axis rather than just
       | time. I think selector length would be wrong, but something like
       | selector complexity, or how robust the selector is to updates.
       | 
       | I scored 3m 50s, but felt like some of my selectors were a bit
       | 'dirty'.
        
         | _Microft wrote:
         | The timer encourages quick and dirty solutions. It took me a
         | while to think of _:is(input, button):not([disabled])_ instead
         | of a longer solution that I used at first. Another example was
         | _span[data-item]_ which is enough to mark exactly the required
         | items at that level but I had found a longer, more specific
         | selector for that first.
        
           | chrismorgan wrote:
           | > _It took me a while to think of_ :is(input,
           | button):not([disabled]) _instead of a longer solution that I
           | used at first._
           | 
           | The intended solution is just _:enabled_. This is where I
           | think this project has failed badly in its stated goal to
           | "improve your CSS knowledge", because all it offers in that
           | direction is a little hint link; to actually _teach_ , it
           | needs a set of proposed solutions, and at the end show you
           | any where you differed.
           | 
           | Such a thing might also help suggesting just _[data-item]_
           | instead of the needlessly-more-specific _span[data-item]_.
           | And also whether _:nth-child(2n+3)_ was the intended solution
           | on one of them.
        
         | jamiethompson wrote:
         | I definitely "cheated" some of these by throwing in something
         | horribly verbose rather than whatever a more correct solution
         | would be
        
           | Vinnl wrote:
           | I felt dirty when I did something like
           | #one, #three, #five, #six, #nine
           | 
           | (Or whatever the elements we had to select were.)
        
             | dotancohen wrote:
             | Exactly. All the previous questions had real, elegant
             | answers. This one felt like whacking the mole was
             | _possible_, but not the right way.
        
             | maaaaattttt wrote:
             | Same here, and to be honest I'm still not sure what the
             | clean solution would be for this level. With that
             | particular html structure and class/id usage there maybe
             | isn't any...
        
               | dagurp wrote:
               | The hint suggests doing it this way. This solution is
               | clean but it isn't very elegant.
        
       | jdefelice wrote:
       | I got stuck on level 7 because I forgot id selectors where a
       | thing.
        
         | mlajtos wrote:
         | I also forgot, but "reinvented" them - `[id="foo"]`
        
         | jacobmischka wrote:
         | Ha, I also thought they were class selectors for a while too, I
         | think because I usually put id before class when I'm writing
         | html.
        
       | MrPatan wrote:
       | 4:26, but there were a lot of commas sometimes...
        
       | 255 wrote:
       | I like it good job!!
       | 
       | I would extend its usefulness by rewarding shorter answers, as
       | you could cheat a lot by using long nth-child selectors for
       | everything which is basically unusable in actual stylesheets
        
       | 0lucky wrote:
       | This is great! I learned a lot in 28 mins :p
        
       | emaro wrote:
       | Nice! I completed it in 05:40:2. Would be fun to have more levels
       | and/or scoring criteria.
        
       | partiallypro wrote:
       | I know most rules that exist but don't always remember them off
       | the top of my head so I look them up. That being said, I was not
       | actually aware of :not
        
       | soperj wrote:
       | This was really good. I knew all the rules, but took me a bit to
       | remember each of them. Did it in 10 minutes.
        
       | grenoire wrote:
       | 5:25, not terrible. Couple of them I was able to brute-force,
       | some of them I realised the easy solution as I was brute-forcing!
       | It's fun, :not(...) is godsend.
        
         | sdoering wrote:
         | Thank you. Didn't know of :not. Just looked it up. Seems like
         | it could help me in a current situation.
         | 
         | Thanks.
        
       | [deleted]
        
       | superasn wrote:
       | Very fun game. There needs to be a golf mode where you get the
       | right answer with the shortest selector just for fun!
        
       | proee wrote:
       | This is a nice project. Is there anything similar for learning to
       | program?
        
       | throwoutway wrote:
       | This is a nice project. Could you talk about how you made the
       | game?
        
       ___________________________________________________________________
       (page generated 2022-01-17 23:01 UTC)