8 ms·
Show HN: CSS Speedrun – A small game to test and improve your CSS knowledge
- sam_goody 5y agoTook 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 5y agoI agree, although there are hint links on each answer which generally give you the selector you are "intended" to use
- emaro 5y agoNice! I completed it in 05:40:2. Would be fun to have more levels and/or scoring criteria.
- Zekio 5y agoMore 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
- codeptualize 5y agoThat was honestly quite fun. I did 08:04:7
- dotancohen 5y agoI agree, even as a backend dev I had a lot more fun with this than I expected. 08:19:6, just slightly behind you.
- deleted 5y ago[deleted]
- iheredia 5y ago* 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 5y agoHowever, 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 https://developer.mozilla.org/en-US/docs/Web/CSS/:not
- grenoire 5y ago5: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 5y agoThank you. Didn't know of :not. Just looked it up. Seems like it could help me in a current situation. Thanks.
- mcv 5y ago7: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 5y agoDid you look at the hints? I learned a bit from them.
- superasn 5y agoVery fun game. There needs to be a golf mode where you get the right answer with the shortest selector just for fun!
- 414owen 5y agoHuh, I wrote a very similar game a while ago. Select elements with CSS selectors to get to the next level: https://select.pink/ https://select.pink/ Mine displays the elements as nested blocks, instead of printing a tree.
- naseemali925 5y agoThanks for sharing, learnt a few more CSS selectors.
- fgeiger 5y agoWow, nice. I like this even better then the OP. In particular how the levels naturally progress and how the game actively teaches concepts.
- aurbano 5y agoAwesome stuff! I learned a few new selectors, thanks :)
- 414owen 5y agoThanks :) I actually posted https://select.pink/ https://select.pink/ to HN ages ago, but it died in `new`: https://news.ycombinator.com/item?id=24959045 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 5y agoThis is terrific! Do note that IDs are document unique. I found a duplicate id on the `#pan.cake` exercise.
- chrismorgan 5y agoMinor 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.)
- Vincenius 5y agoGood point - fixed it :)
- jacobmischka 5y agoLong live XHTML syntax for self-closing tags!
- DaiPlusPlus 5y ago> 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?
- chrismorgan 5y agoIt teaches the wrong mental model for the HTML syntax. If you’re using the XML syntax, by all means use self-closing tags, but very few things do that, and almost all of them are over a decade old. (I set up gitweb last week, and it uses XML syntax HTML, and needs it because it nests links, which is invalid but works in XML syntax, and impossible in HTML syntax. It also does other wrong things like omitting the <tbody> in tables, which is inserted automatically in HTML syntax.) What I observe is that it’s quite common for people to put in the trailing slash on void elements, but that it’s almost never (<1%) applied consistently (you’ll see some <link/> and some <link>) so that any XML syntax compatibility argument is void, and I’ve come across at least one person who thought it was necessary and at least one person who thought it closed tags (and thus could be applied to non-void elements) and was surprised that it didn’t. XHTML is dead. XML syntax for HTML is on indefinite life support (with no prospect of being either revived or removed). HTML is not XML: the HTML and XML syntaxes are mutually incompatible (e.g. <noscript> isn’t possible in XML syntax, and <script>"&"</script> produces a different result). Writing your HTML in more XMLy ways isn’t about higher standards, but about making it something that it’s not. It’s wrong to use XML processing infrastructure on HTML documents unless they’re marked as XML syntax, because even if it doesn’t fail, it may interpret things incorrectly.
- TomAnthony 5y agoThis 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'.
- jamiethompson 5y agoI definitely "cheated" some of these by throwing in something horribly verbose rather than whatever a more correct solution would be
- Vinnl 5y agoI felt dirty when I did something like #one, #three, #five, #six, #nine (Or whatever the elements we had to select were.)
- maaaaattttt 5y agoSame 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 5y agoThe hint suggests doing it this way. This solution is clean but it isn't very elegant.
- dotancohen 5y agoExactly. All the previous questions had real, elegant answers. This one felt like whacking the mole was _possible_, but not the right way.
- _Microft 5y agoThe 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.
- MrPatan 5y ago4:26, but there were a lot of commas sometimes...
- 255 5y agoI 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 5y agoThis is great! I learned a lot in 28 mins :p
- jdefelice 5y agoI got stuck on level 7 because I forgot id selectors where a thing.
- jacobmischka 5y agoHa, 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.
- mlajtos 5y agoI also forgot, but "reinvented" them – `[id="foo"]`
- woolion 5y agoNice 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 5y agoI 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://www.youtube.com/watch?v=W0fDO4IuO-M&ab_channel=AudiobookstoLearnFrench https://www.youtube.com/watch?v=W0fDO4IuO-M&ab_channel=Audio...), programmed instruction (behavior analysis), and transfer of learning.
- 411111111111111 5y agoi 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
- youssefabdelm 5y agoOh thanks for correcting me! My bad, I did not see that.
- throwoutway 5y agoThis is a nice project. Could you talk about how you made the game?
- nayuki 5y agoI used the child combinator (>) and adjacent sibling combinator (+) a lot. I think these aren't used much in real-world code?
- throwaddzuzxd 5y agoI 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.
- partiallypro 5y agoI 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
- Nadya 5y ago4: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 5y ago2: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.
- mrjay42 5y agoI 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_selectors https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_s...). But I did not find how to do it :'(
- 411111111111111 5y agothats strange, i could just use i think `div[data-item]` and it worked for me
- mrjay42 5y agoOooh 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 ^^
- deleted 5y ago[deleted]
- proee 5y agoThis is a nice project. Is there anything similar for learning to program?
- tiffanyh 5y agoLove the project. Wish it had the answer as well, not just hint.
- soperj 5y agoLet me know which ones you want answers for and I can put them in.
- soperj 5y agoActually, 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)
- tiffanyh 5y agoThanks so much!
- soperj 5y agoNo worries. There's lots of documentation, but happy to help if you have a specific question.
- mcv 5y ago> li:nth-child(2n+3) I was not aware of this. I did li:nth-child(3), li:nth-child(5), li:nth-child(7) but was thoroughly unhappy about it. Thanks for showing the better solution.
- soperj 5y agoThis was really good. I knew all the rules, but took me a bit to remember each of them. Did it in 10 minutes.