• 3 Posts
  • 26 Comments
Joined 1 year ago
cake
Cake day: June 30th, 2023

help-circle




  • Paradox@lemdro.idOPtoProgramming@beehaw.orgCSS is fun again
    link
    fedilink
    English
    arrow-up
    1
    ·
    8 months ago

    They can both model any color equally well, it’s just oklch works even closer to how we perceive colors changing. LAB and all derivatives are in Cartesian space, with luminance, a, and b being the defining axises. Luminance is self explanatory, but a and b are just axises of how much red/green and blue/yellow there is. It can be difficult to think of a color in how much blue it is, for example, when the color is something like nearly pure red. They both affect the hue output, so varying one can create strange, unintuitive colors

    LCH works in polar space, like a color wheel. L is still luminance, c is the “colorfulness” and h is the hue. H and C let you set the same values a and b would, but in a more human way. We’re used to thinking about colors changing independent of how much of a color there is, and that’s what LCH does. Vary only the h and you get very different colors. Vary only the c and you get the same color but in different amounts of saturation, from full color to no color




  • Data comes out as a map or keyword list, which is then turned into the repository struct in question. If you want raw db data you can get that too. And you can have multiple structs that are backed by the same persistent dataset. It’s quite elegant.

    Queries themselves are constructed using a language that is near SQL, but far more composable:

    Repo.one(from p in Post, join: c in assoc(p, :comments), where: p.id == ^post_id)
    

    Queries themselves are composable

    query = from u in User, where: u.age > 18
    
    query = from u in query, select: u.name
    

    And can be written in a keyword style, like the above examples, or a functional style, like the rest of elixir:

    User
    |> where([u], u.age > 18)
    |> select([u], u.name)
    

    None of these “queries” will execute until you tell the Repo to do something. For that, you have commands like Repo.all and Repo.one, the latter of which sticks a limit: 1 on the end of the provided query


  • I much prefer the repository pattern, as used by sequel and Ecto

    Your models are essentially just enhanced structs. They hold information about the shape of data. Generally don’t hold any validations or logic related to storing the data. You perform changes on the data using changesets, which handle validation and generating the transaction to persist the data

    It works extremely well, and I’ve yet to encounter the funky problems ActiveRecord could give you


  • The amount of code you save grows with your codebase. It was 18% for that one, small example. In a larger codebase it can be quite a bit higher.

    While I have, more or less, moved to just writing html-style templates, I do miss how easy it was to refactor something to have a different tag name. Vim and other editors do have shortcuts that make it easy to change both the opening and closing tag, but in indent based syntax, I didn’t have to worry about this. There was only one tag to change.


  • CSS has been growing a lot of “super powers” lately, that used to require a pre-processor. Custom properties (variables), nesting, calc, and color-mix used to be things we’d reach for a preprocessor for, but can now be done 100% in pure CSS. And generally, the CSS based versions are better than their old preprocessor counterparts. calc can mix units, so you can easily do things like calc(100% - 1rem) to subtract a rem from 100% of the parent container. Can’t do that in Sass. Custom properties can be set by Javascript, or by media queries, and follow CSS scoping rules. Thats how I handle light/dark mode on my site.


  • Builder is mostly targeted at building XML files, and so compared to XML its fairly terse. HTML is just a nice also-have. There are template langs in ruby that are a lot closer to the Elixir temple variant, but I can’t remember any of them off the top of my head haha.

    A good template would make interfacing “easy”. JSX[1] is a very good example of how you can interface quite easily, and the templates used in Surface work really well to bridge some of the complexities of a server-rendered but client-dependent syntax.


    1. I know JSX isn’t a template language, the differences don’t matter for the purpose of this discussion ↩︎


  • Nim does a lot of things very well, I love writing JSON and parsing JSON in Nim, probably the best experience I’ve had with JSON, followed shortly by just implementing it as a protocol in Elixir.

    Karax’s pattern of just using language constructs to assemble HTML isn’t really novel, as nice as it is; Ruby has had one for ages in Builder (and several offshoots), Elixir has Temple, and there are probably some in other languages. They’re sort of one level of abstraction less than slim/haml, but its quite pleasant writing them. But they suffer some of the same issues Slim/Haml suffer, but also can suffer when trying to use them with component frameworks, or anything that exposes custom tags. This can, of course, be solved via metaprogramming or language-level templates, but it is a concern





  • I mentioned some of this in another comment in this thread[1], but CSS has gotten tremendously better since Sass was first introduced in the 00s. Many features we used are now native to CSS, and can be used in your browser, today. Some of them are even better than their sass variants, or at least have special abilities sass doesn’t. calc() comes to mind, as it can mix and match units in a way a preprocessor just cant. You can do calc(100% - 10px), which is good for all sorts of stupid corner cases.

    And native CSS nesting is basically 1:1 with how Sass does it:

    .parent {
      font-weight: 600;
    
      &:hover {
        background: purple;
      }
    
      .child {
        font-weight: 900;
      }
    
      @media screen and (max-width: 800px) {
        display: none;
      }
    }
    

    I still use Sass or Stylus[2] on virtually all of my projects, but its nice to not have to when you just need to get something out or write a userstyle or something.


    1. Not sure how to provide an instance agnostic link, the few things I’ve seen people attempt didn’t work, but here’s the lemdro.id link ↩︎

    2. I’m largely giving up on Stylus, its sadly unmaintained. My favorite preprocessor though; takes .sass (indented) style to a whole new level on what you can omit ↩︎


  • I’d encourage you to take a look at modern CSS with a fresh eye. It’s gotten really good. Good enough I’ve got another blog post in the works talking about how much goddamned fun its gotten. In the last few years alone, we’ve got sass-style nesting, parent selectors (!), combinator selectors (roughly like list comprehensions in their ability to fill out a matrix of potential selectables), color functions, and far more.



  • Well, you get all the real advantages of real CSS. The browser tools work. Various other preprocessors work. You can use timesavers like Sass or Less or whatever else.

    The biggest advantage, imo, of using a component based design, where components handle not only the styling but the entire appearance of a “thing”, is that you make the contracts for what that thing has to support explicit. If your button needs to be able to change colors, you can add a prop that exposes that ability. If it needs to change sizes, again, that can be exposed by a prop. But they aren’t by default.

    You can sort of accomplish this in “real” css using attributes carefully, but its not as elegant.