Live data from Hacker News

Layout-Isolated Components

visly.app

11–20 of 36 posts

Re: Layout-Isolated Components

#11
post #3

So, the article talks about what not to do. Are there good examples of layout isolated components inside a complex UI?

We make a browser-based game development IDE (www.construct.net), and IMO an important aspect of this is CSS containment: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Contain...

You can use 'contain' CSS properties to guarantee that layout inside the element won't affect anything outside it and vice versa. 'contain: strict' is basically a bulletproof container for arbitrary content, with performance benefits too. I'm not sure if it covers everything the article was trying to achieve, but it seems surprising not to mention it.

Re: Layout-Isolated Components

#12

While I agree with all of the problem statements in this article, I don't quite agree with the proposed solution of just exposing style props for parents to pass through arbitrary values, at least not as a general solution (it could still be the appropriate solution for certain special cases). I think this approach actually results in _less_ useful component isolation in that you can no longer reason about layout of…

reusable components [...] should render nothing outside of it (including empty space, i.e. margins).

Could collapsing margins be an exception to this rule, in principle?

I’ve mostly worked in Android, iOS and React Native, none of which have collapsing margins. But I’ve often wished they had, as it would make some layouts a lot simpler! It would be great to just smoosh components together and have them agree between themselves how much space is needed.

HTML has collapsing margins but they seem kind of half-baked. Is there enough functionality there to be useful, or is it best avoided entirely?

Re: Layout-Isolated Components

#13
post #4

@media queries based on browser width are especially bad. Unfortunately there is no css way for stylings dependent on the width of the _component_ itself.

It's not CSS based, but I've had reasonable success with ResizeObserver based component size queries, at least in the context of small components that don't accept other nodes to render.

I've found this hook (https://github.com/react-spring/react-use-measure) to be reasonably robust, as long as you only use the size properties and don't rely on the accuracy of the positioning properties, which is not something that ResizeObserver is designed to handle (it can get out of date when the component moves due to dynamic content appearing/disappearing around it without actually resizing: https://github.com/react-spring/react-use-measure/issues/9).

It remains to be seen how this could scale when applied to larger "container" type components and the entire app though, as I imagine cascading re-renders as higher level elements resize could become an issue. Curious if people have experience with using ResizeObserver for component size queries at scale?

Re: Layout-Isolated Components

#14

Or, “Object-oriented” Remember when we were building our apps as a set of screens and pages instead of thinking in components? Sure, but I also remember building web apps in GWT, using a toolkit of reusable widgets, with an OO interface. Edit to add: I guess I’m more agreeing with the author than arguing with them; I just find it amusing how what goes around comes around.

How does it become any more object-oriented?

I saw it more as "purely functional", where components are the functions and styling outside of the component is a side-effect. Avoiding side-effects like margin or align-self makes components more like pure functions than objects IMO.

Re: Layout-Isolated Components

#15

Or, “Object-oriented” Remember when we were building our apps as a set of screens and pages instead of thinking in components? Sure, but I also remember building web apps in GWT, using a toolkit of reusable widgets, with an OO interface. Edit to add: I guess I’m more agreeing with the author than arguing with them; I just find it amusing how what goes around comes around.

I would love it if the new component revolution worked for sites not using Javascript frameworks.

Re: Layout-Isolated Components

#16
post #14

Or, “Object-oriented” Remember when we were building our apps as a set of screens and pages instead of thinking in components? Sure, but I also remember building web apps in GWT, using a toolkit of reusable widgets, with an OO interface. Edit to add: I guess I’m more agreeing with the author than arguing with them; I just find it amusing how what goes around comes around.

How does it become any more object-oriented? I saw it more as "purely functional", where components are the functions and styling outside of the component is a side-effect. Avoiding side-effects like margin or align-self makes components more like pure functions than objects IMO.

Margins and align-self aren’t side-effects. Their semantics are consistent and reproducible and depend only on the context a component is placed in, just as a property like width does.

They’re awkward because they have bigger knock-on effects on the overall layout of components within the parent.

In an OO mindset, I see this as being all about what interfaces your object exposes. For something like a button or slider control, it obviously exposes an action callback of some kind. But it also exposes a generic “child component” interface, which is the only thing a generic parent component cares about.

What are useful things and what are obnoxious things for a child component to do? Flexibly adapting itself to a range of sizes is useful. Demanding that it should be centered is obnoxious. In fact it would be hard to express at all in most OO widget toolkits. So I think this problem is very closely related to good OO design.

Re: Layout-Isolated Components

#17

While I agree with all of the problem statements in this article, I don't quite agree with the proposed solution of just exposing style props for parents to pass through arbitrary values, at least not as a general solution (it could still be the appropriate solution for certain special cases). I think this approach actually results in _less_ useful component isolation in that you can no longer reason about layout of…

OP here. Totally agree passing arbitrary styles down in props is not a great solution and makes to incredibly hard to reason about components. We defined explicitly using typescript the styles which can be set from the parent which makes it much easier to reason about and we can even use the "find all references" feature of VSCode to identify usages.

Re: Layout-Isolated Components

#18
> Layout-isolated component - A component that is unaffected by the parent it is placed within, and does not itself affect the size and position of its siblings.

I'm honestly still surprised that this isn't the default. Beyond maintainability, it's an obvious security problem, which clickjacking made apparent years ago.

The security implications of user interface API apparently isn't well understood outside the capability security community though:

Design of the EROS Trusted Window System, http://srl.cs.jhu.edu/courses/600.439/shap04windowsystem.pdf

> Remember when we were building our apps as a set of screens and pages instead of thinking in components?

If pages were components in the browser, there wouldn't be any difference. Xanadu had something like this way back in the early 90s, ie. page transclusion.

Re: Layout-Isolated Components

#19
A fundamental problem of building isolated components in HTML/CSS is that the CSS `display` property sets both an element's inner layout (how it lays out its children) and its outer layout (how it is laid inside it parent).

E.g. you have to make an element "display: inline-flex" to make it an inline flexbox. You can't just make it "flex" and have the parent decide whether it is inline, a block or whatever.

The consequence of this is that a parent component cannot properly layout a child component without knowing its internal layout structure. And if it doesn't don't know the child's layout (if its dynamically supplied for example) then it can't safely do anything with it. So long as this limitation exists, there will never be true layout encapsulation on the web platform.

For a while, the CSS Working Group planned to address this problem through the introduction of separate `display-inside` and `display-outside` properties. This would mean an element could specify its internal layout using `display-inside` while its parent could control its external layout using `display-outside`. Then, in their wisdom, they dropped it from the spec[1].

I mean, it's not like developing with encapsulated components is a popular approach on the web nowadays. It's not like many people are using React, or Angular, or Vue, or Web Components—the W3C's own goddamn multi-year effort to push component-based development—so why bother wasting time adding features that would help?

[1] https://drafts.csswg.org/css-display/#changes-wd

Re: Layout-Isolated Components

#20
post #14

Earlier quoted context omitted.

How does it become any more object-oriented? I saw it more as "purely functional", where components are the functions and styling outside of the component is a side-effect. Avoiding side-effects like margin or align-self makes components more like pure functions than objects IMO.

Margins and align-self aren’t side-effects. Their semantics are consistent and reproducible and depend only on the context a component is placed in, just as a property like width does. They’re awkward because they have bigger knock-on effects on the overall layout of components within the parent. In an OO mindset, I see this as being all about what interfaces your object exposes. For something like a button or slider…

Their semantics might be consistent, but they sort of leak into the parent. Height and width are local to what the component renders, and they don't depend on the parent (as long as they aren't relative sizes). But things like margin and align-self change how the parent renders all of its children.

In other words, the view rendered by the component is a function of properties like height and width. But when you throw in margin or align-self, the component now depends on its siblings.

The OO perspective is interesting — I agree that it effectively makes these things hard to express. I now think that it's more of a problem relating to encapsulation and isolation. OO would isolate it through a child component interface while FP would have a function that can't affect siblings.

Post reply on HN