Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Pylon – Declarative layout primitives for CSS and HTML (almonk.github.io)
148 points by sgottit on June 11, 2019 | hide | past | favorite | 75 comments


I enjoy seeing other people's solution, but since I really learned the power of grid, most of this is overdone with flex.

As an example, here's how you can make a vstack with grid.

  vstack {
    display:grid;
  }
It's ridiculously simple and clean, works with all the elements without extra wrappers, no margins, no cleaning up trailing spaces, etc... add spacing class using "grid-gap" and it's the near perfect solution.

The hstack example is more complicated, because you simply have to choose widths, there is no getting around this, even with flexbox. (unless you want to totally give up control of the layout to "auto".)

The spacing classes are clever, and I may adopt some of this method. (I use grid gap, I only have 2 sizes) With the "Spacers" example, a width of 1fr works using grid.

Flex beats grid with some natural overflow capabilities (row wrap), but other than that, flex is not great for this kind of thing.

Since there's only a few examples, I suspect this person will be adding more in the future.

Edit: For declarative things like this, I think there should be one assumption. I use vertical in web interfaces. This means one less option to remember. (ie, by default everything is vertical)

Edit2: With an unknown number of items, flex is probably preferable for horizontal items for simple columns. But that is only if you don't care about the widths of the columns too much as well.


Only problem with grid vs flex is browser support. I opt for flex still because it's got better support.


Since the topic is "new framework", I would not advise investing in a system that is not ideal long term just because of a very minor support percent difference today. (looks like 6% of the world based on caniuse.com, but your audience may vary of course)

The benefit of an assumption like "everything by default is vertical", then the few people without grid support, but with flex, will have a "mostly" ok display.

Also, it's not hard to have a fallback to flex for horizontal items. (the only place it would really matter)


I feel like this would actually be one of the strengths of using a framework. I can abstract away my own styling to the framework, and the framework can upgrade from flexbox to grid without requiring me to change any of my own code.


Yep, I agree, seems like we are on the same page. I made my own framework based on my specific uses, so I even get to control when the fallbacks are removed, and deal with any of the fallout if there's issues.

I kind of think that at one point, everyone that works a lot with front end web development should make their own framework. It helps you learn to make long term decisions, deal with design iterations where you have lots of wide spread use of older systems and many other things that help you make wiser decisions in day to day interface design. But also it can help you see where things like Bootstrap are helpful and where it is not.


I like this, but my 20 years in web dev can't help but chuckle. Remember when tables were declared evil for layout, so we had the shit show of trying to use CSS floats for everything, so then we added flexbox, and then grid, and here is a nice set of elements that is basically, well, somewhat less useful than tables for layout.

Don't mean to bash the poster, I just think it's interesting in the "everything old is new again" vain.


Regarding tables, try view source on this very thread. Some of you might be surprised :)


Good God man, why did you have to point that out?!?


¯\_(ツ)_/¯


I work on an older project with some folks that never got the memo about tables being evil for layout. In my experience, they've actually been quite easy to work with. Granted, we develop for a fixed screen width. Why were tables declared evil?


Aside from the semantic HTML movement, they're clunky and verbose, more difficult to break up into reusable components, and table rendering is more expensive than the equivalent layouts with non-table elements and CSS (at least that was my experience last time I tried profiling a table with hundreds of rows).

Edit: they also have a lot of intrinsic layout behavior that can be difficult to predict once you start getting into more complex layouts than header, sidebar, and footer.


They didn’t flex like flexbox. When smaller laptop screens and eventually mobile devices appeared on the scene, tables would often extend past the screen’s boundaries.


They mix content and presentation. If you separate content from presentation, then you can have a presentation for desktop an another for mobile. Also, you can totally change the layout without the need to change your HTML, as showcased in http://www.csszengarden.com/


The whole concept of separated “content” form “presentation” in UI is a bunch of nonsense. Maybe it works somewhere in some very limited sense, but I’ve yet to see anything complex that separates these things.


In the specific case of html and css I agree that it rarely works. There are a few examples like subreddit css, but in general html does to much layout to meaningfully separate content from layout. Xml and XSLT is a much better separation, with Xml containing pure content and Xslt transforming that into XHTML with CSS for presentation. But that never got much adoption.

In other domains separating content from presentation works well. But in web development the incentives don't align with that idea.


Agreed. The real answer, as you noted, is that presentation really is HTML+CSS. You can join it with content in JSON (or XML if you want) via client or server side templating.

It actually gets you pretty close to MVC or whatever MVVC is maybe? Is that still a thing?


It’s really not nonsense. Make a text file with line breaks to force a line length, and then make a non-trivial edit to the content. You’ll have to move all the line-breaks too. It’s awful.

If you’d instead left presentation to the display tool, you’d only need to change the content.

The HTML presentation/content argument is this scaled up.


> Make a text file with line breaks to force a line length, and then make a non-trivial edit to the content. You’ll have to move all the line-breaks too. It’s awful.

But Emacs does that for me if I press M-q.


Exactly!

Your editor is also your presentation tool here, and it knows where all the line breaks should be, so it can do the edits for you. It works those around the content. If you hadn't included the line-breaks in the first place, it wouldn't even have needed to do that (well, ok, it would to "soft-wrap").

If you passed/copied the file to someone who prefers a 78 character line to your 100 character line (or uses a machine from the early 80s for retro-cyberpunk chic), when they render the file, several things could happen: - their viewer/wditor might add temporary line-breaks to soft-wrap, in which case they'll see some short and some long lines - their viewer/editor might add hard-wrap line-breaks at 78 chars. This would remove all your 100 char ones, and could potentially break your content because it might not see the difference between a "wrap" and a "new paragraph".

In the second case, when you get the file back later on, the content wont suit your preference for 100 character lines.

When the presentation is kept out of the content, none of this happens.

My point was that even in something as simple as a text file, adding presentation commands (line breaks), adds work, or hinders accessibility.

Scale that up to HTML and the wider range of possible presentation options. Say you used the old-school inline colouring options. Maybe you find green text on red backgrounds really fun to read. You encode that into the content (the markup). Pass this file on to someone with red-green colourblindness (c7% of XY-chromosome carrying humans[0]) and they wont be able to read your file at all.

[0]: https://www.colour-blindness.com/general/prevalence/


The separation of content from presentation is one of the primary purposes of MVC frameworks. The model (content) is separated from the view (presentation) by an abstraction layer (controller).


I really need to tell you... html is already only presentation. The content is in the backend system


Screen reader pedantry, I think; also they're "not semantic markup". The idea was that tables should only be used if the content was genuinely a table.


"Screen reader pedantry" sure is a pretty abrasive way of describing creating websites for people.


You're right, it's unnecessarily abrasive. But it is, as far as I can tell, a very minority use case, and these days most of the reader software has adapted. If you see some of the DOM horrors inflicted by Facebook, then suddenly tables look positively readable.

Perhaps what should have happened was the defining of a "table-layout" tag that behaves exactly the same as "table" except it's understood to be for visual presentation only. Flexbox almost achieves this, but for some reason isn't as popular.


There is such a thing in CSS. Display: table, table-cell, etc. It's supposed to make content render exactly as if it were cast in an Html table.


All the table elements just have special values for the CSS "display" property. You can apply these to divs or any elements and get table layout.


Brain-washers and adblockers playing catch-up leaving a scorched-DOM behind.

Also, flexbox is very popular in my experience.


One man's pedantry is another blind man's attention to detail. Or ability to participate in society.


> Why were tables declared evil?

If you use them for layout, you're not respecting the semantic meaning of tags.


One answer reveals itself by just switching two lines around:

> Why were tables declared evil? > Granted, we develop for a fixed screen width.

Personally, I was always more disturbed by the anti-semanticism of the layout use of tables. But I guess at some point the web developer community just really stopped caring about such issues. Or at least that's my takeaway of the common atrocity of style attributes on individual elements that css-in-js approaches frequently produce.


I think the people really pushing for the Semantic Web kind of gave up. You hardly ever hear that term anymore.

I guess the value proposition of "You can add a whole bunch of complexity to your webpage that won't affect what people see so robots can scrape your page easier" didn't really resonate with developers. Also, the proposals I saw were much too granular and focused on people writing scientific papers on the web. It wasn't a good mesh for the "garbage" web, which is like 99% of everything.


"Semantic Web" and using the semantically correct tags for HTML aren't really the same thing.


There’s nothing non-semantic about inline styles. And most css-in-js convert thise inline styles to a separate stylesheet with classnames.

I’d say web developers care much mire about semantics now than they did ten years ago. At least now you can finally have meaningful conversations around accessibility and screen readers.


> But I guess at some point the web developer community just really stopped caring about such issues.

Any plan that depends on people caring won't survive contact with actual people.


Sometimes simplicity is more important than expressiveness, when the scale is small. See markdown for an example.

So I for one like this super-compact and simple language, it's good for making simple interfaces quickly. It's unlikely to break in subtle ways on mobile, or so I hope.

Internally a solution like this may use CSS grids, flexbox, or any new hotness that makes thing easier to implement.

Of course this is going to get ugly, or outright break, if used at a large enough scale. But very often you manifestly do not have a large scale, and never going to.


And in that 20 years you haven't encountered custom elements/web components, etc, etc?


Wow. So many kill-joys in this thread.

I think the project is neat. It certainly is an opinionated way of doing a layout and it reads quite nicely. If CSS classes were provided as an alternative I think the project might have more adopters.

Good work :)


Most of the critics seemed to be about pita caused by layout methods in general when rendering them on variable size screens, and not necessarily the Pylon methods themselves.

I agree with you, I think this is clean and easy to use.

Personally, I've stuck with Bootstrap for quite awhile now. It's not perfect but it's pretty good, well documented, and I work to keep it simple. So I don't really use a lot of what Bootstrap does and that's why this project appeals to me.


Reminds me very much of XUL, Mozilla's XML-based language for UI. https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XUL

In a prior life I developed a slew of XUL apps, including a full-suite medical record system and billing system. It had its quirks, but for a developer-heavy (and design-light) firm it was a great way to build standard, predictable, and accessible UIs.


Fun idea. The naming is weird as pylon used to be a python web framework but since it's not going to have any chance to become popular, overriding it seems alright.


I don’t know. Any package name that contains the string py makes me assume it’s python.


I felt the same way, I was thinking this was some sort of rendering engine to use with python to generate html layouts


The resulting HTML is not great, but the dev experience looks super nice.

Maybe we need to introduce HTML transpilers now :)


I've been building and using various forms of HTML transpilers for several years, as part of a build step or "JIT" during server-side rendering.

The main advantage I see is the ability to extend HTML to have layout/templating functions, building up a simple DSL for frontend devs and editors. Since the target userbase is already familiar with HTML syntax, it's easy to learn and gives them "super powers" - for example, an <include> tag that imports another HTML file/partial.

Another use case I've used in a number of sites/applications: chaining a Markdown parser, an HTML transpiler, and a React renderer for the HTML "AST". Among other things, it renders internal links <a> as <Link> components of the router.

And the rabbit hole goes deep: the XML/HTML syntax is actually able to represent "programs" in a Lisp-like manner. If the angle brackets are too noisy, one can use Jade/Pug syntax to generate the same AST.

In the end, the traspiler should render the result in standards-compliant HTML. This Pylon project doesn't transpile anything, so the result contains undefined tags which the browser treats as HTMLUnknownElement [0]. The bottom line though, is that it works - and I've seen numerous projects in the wild taking advantage of this behavior.

I'd also like to mention the posthtml project [1]. I haven't used it myself, but a generic HTML transpiler has great potential in my opinion.

[0] https://developer.mozilla.org/en-US/docs/Web/API/HTMLUnknown...

[1] https://github.com/posthtml/posthtml


> And the rabbit hole goes deep: the XML/HTML syntax is actually able to represent "programs" in a Lisp-like manner.

XML was always a poor man's s-expression.

And for all the sins of SGML, tags lend themselves beautifully to templating because they can represent code as data just as Lisp does.



Only one layer of transpilation? Rookie numbers. I can get javascript up to 4 or 5 layers on a good day.


Hah!


Very cool, but I'd like to point out that unless/until this gets very popular to where Google changes their practices, it wrecks certain SEO perks (though so do a lot of fancy practices). Google still really likes plain old HTML primitives like <OL> or <UL> for lists, <TABLE> for tables, <P> for paragraph. Their featured snippets appear to be capable of extracting info that isn't in that form and bumping it to the top of results, but to prefer not to. My $.02 from starting to learn that game.


Why have the alignment done relative to the direction of the stack? I’ve wondered the reason for this with Flexbox as well.

It’s very hard to remember and unintuitive. My guess is something to do with responsiveness?

To me, alignX and alignY (with an align shorthand) are always clear. And the amount of times I’m changing between the two is nearly 0 so far in a large app.


The intent is nice, in fact this is what React Native for Web does as well with the difference that accessibility and semantics are preserved because JS comes to the rescue.

That said for pure layout stuff I actually think that this library is cool. <view> is totally fine.

<py-view> (or a sexier prefix) would even be valid HTML


I think this seems pretty cool. I can see using it for all sorts of projects with minimalist needs, e.g. quick prototyping, interview coding assignments, admin consoles.


You must construct additional Pylons!


SwiftUI should go more the jsx/HTML way. Not the other way around!


Why? I think both approaches are valid. SwiftUI separates data from representation. jsx+css is comparable. Pure HTML always contains some representation so the boundary is less clear.


This most likely breaks accessibility especially in lists.

But it does look nice :)


So basically you're abusing the fact that (modern) browsers treat unknown tags more or less as divs and built a small CSS framework with these names.

I understand how that it can feel familiar to Swift devs, and also realized by reading the source that the upside of using unknown tags means they don't have any base style that you'd have to override.

But really, you're breaking all HTML semantics and your markup is not accessible. It could work as a set of React/Vue/Whatever components or even Web components (probably the best way to achieve what you're trying to do), but as bare HTML it doesn't.


> So basically you're abusing the fact that (modern) browsers treat unknown tags more or less as divs and built a small CSS framework with these names.

The spec allows custom elements[0] and pretty much requires this behaviour.

> you're breaking all HTML semantics and your markup is not accessible.

Calling the markup non-accessible is defensible[1], but it doesn't break HTML semantics in any way.

[0] https://html.spec.whatwg.org/multipage/custom-elements.html#...

[1] though it wouldn't be more accessible as a stack of divs and the custom element can be aria-tagged[2], in the browsers supporting it it's also possible to use customised elements but here there's little of interest

[2] https://html.spec.whatwg.org/multipage/custom-elements.html#...


Custom element names must contain a hyphen for forwards-compatibility, and these do not.

https://html.spec.whatwg.org/multipage/custom-elements.html#...


The Custom Elements spec requires all custom elements to have a hyphenated name.


Came to say the same thing. Seems odd to me, personally. Why not just make them class names, and you could probably still get an even smaller sized framework (if that was the main goal)?


I think the idea is to also abstract away the choice of elements in favor of familiar container names. Make it only class names and you're back to a simple CSS framework like tons of others already.


This could work with a build system or as a templating engine. The names and logic is sound, but as you said it makes little senses to use those tags as-is in production.


This looks great!


This has issues:

    <list>
        <hstack spacing=s>
            <div class="icon"></div>
            <text>Westminster</text>
            <spacer></spacer>
            <text>0.5 miles</text>
        </hstack>
        ....
It is more complex then it needs to be, it puts the styling into into the html, it kills all semantic meaning and pollutes the global namespace of element names.

It should be:

    <my-cities>
        <my-city>
            <city-name>Westminster</city-name>
            <city-distance>0.5 miles</city-distance>
        </my-city>
        ....
And then simply style the custom attributes to your liking via css. If these "primitives" would use classnames instead of element names, their styles could be added like this:

    <my-cities class=pylon-list>
        <my-city class=pylon-hstack>
            <city-name>Westminster</city-name>
            <city-distance>0.5 miles</city-distance>
        </my-city>
        ....



I remember playing around with XSL years ago, it kind of blew my mind that more people weren't using it. The bandwidth savings seemed immense. But then I started to run into edge cases, and realised that gzip covered most of the bandwidth difference anyway... but I still maintain it's a super cool idea.


CSS is why we can’t have nice and easy rich UI things in web dev world. And so I downvote you...


Are those custom elements just divs by default or do you need to define them somewhere?


Technically, they should be defined:

https://html.spec.whatwg.org/multipage/custom-elements.html#...

Browsers usually treat undefined nonstandard elements as span-like (flow elements), not div-like (block elements) by default.


They are not divs. They are whatever you call them. If you mean "Are they styled like divs by default?" then also no. Divs are block elements by default while custom elements are inline elements by default.


Modern browsers indeed treat unknown elements as equivalent to divs, but it's officially undefined behavior, up to implementation.


And herein lies the flaw of custom elements: that they don't use a declarative mechanism for exposing their presence in HTML to browsers. Instead, they must be declared by subclassing from built-in element representation classes (using ES6+ class syntax which nobody seems to be using anyway). Now the browser must 1. have JavaScript 2. have JavaScript enabled 3. synchronously execute the subclassing/registration script code text before proceeding with parsing (which browsers do anyway, but at least didn't have to in order to even parse HTML as intended).

Not only that: content of custom elements is treated as fallback content (taken when a particular custom element is not available). However, that content is still subject to HTML parsing and tag omission rules, and tag omission is contextually dependent on the parent element's content model (which a custom element doesn't have since there's no way to register such using the JavaScript API).

There was (?) even the sacked mechanism of "customized built-in elements" which would allow authors to define custom attributes and behaviours for standard HTML elements. Except it doesn't work like that with HTML's enumerated attributes such as `selected` which can have shortforms like `<div selected>` where `selected` is the attribute value not the attribute name, requiring the values of all enumerated attributes be unique among all attributes in a DTD (as in SGML) or at least on a given element.

Sometimes I wonder why the HTML spec authors just had to make every blunder imaginable when there's a very rich theory of formal language and markup languages (eg. SGML and others) dealing exactly with these kind of problems.


Just tried in firefox and as mentioned above they are not block elements but inline:

    <foo>foo</foo>
    <bar>bar</bar>
    <div>div1</div>
    <div>div2</div>
Results in:

    foo bar
    div1
    div2


You're right, they are indeed considered inline elements, not blocks. My bad.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: