Prinzhorn / scrollmeister

Open-source JavaScript framework to declaratively build scrolling experiences
https://www.scrollmeister.com/
MIT License
37 stars 5 forks source link

Media queries / responsive behaviors #1

Open Prinzhorn opened 6 years ago

Prinzhorn commented 6 years ago

In theory this can be done in userland. A responsive behavior could simply overwrite other attributes (behaviors) depending on different conditions. E.g.

<el-meister
    layout="guides: center right"
    responsive="mobile: layout: 'guides: left right';"
>

But nesting attributes as strings inside attributes looks hell and no. Just no.

Instead we can make this part of the very core, since it is an essential feature anyway. A-frame allows the same component (we call it behavior) to be added multiple times by specifying an id using two underscores. E.g. <a-entitiy thing__foo="" thing__bar="">. Inspired by this idea I think we could use a similar naming convention to make behaviors' properties responsive.

The following example defines an element which uses the left and right guides (basically full width) as a default. It also defines a spacing of 10vh. Now if the desktop condition is met, the layout.guides property is overwritten with left center, making the element span the left half. Spacing is untouched.

<el-meister
    layout="guides: left right; spacing: 10vh 10vh;"
    layout_desktop="guides: left center;"
>

These type of conditions could be anything, not just the browser width. A condition is basically a named function, in this case desktop. But you might as well define a touch condition or a ie9 condition. And of course they don't just apply to the layout behavior, but literally every behavior. And since many behaviors add functionality and not just styling, this allows to declaratively change the functionality without writing any code. For the behavior itself this is completely transparent. It doesn't know about conditions. It just receives new props.

In the above example the layout attribute is actually just a shorthand for layout_default. The default condition is always true.

TODO: the conditions need to have an order/specifity. E.g. the default condition has the lowest specifity and will be overwritten be any other matching condition.

TODO: the observedAttributes getter needs to be aware of all possible conditions to add them to the list. To allow custom conditions in userland we face the same issue as with custom behaviors. They need to be specified before the custom element is registered or otherwise the observedAttributes getter won't know about them.

Prinzhorn commented 6 years ago

TODO: the observedAttributes getter needs to be aware of all possible conditions to add them to the list. To allow custom conditions in userland we face the same issue as with custom behaviors. They need to be specified before the custom element is registered or otherwise the observedAttributes getter won't know about them.

done.

Also note: it should be possible to not define the default at all. So using fluidtext_m will only add the fluidtext behavior for m and up. It will be completely removed otherwise.

Prinzhorn commented 6 years ago

Also note: it should be possible to not define the default at all. So using fluidtext_m will only add the fluidtext behavior for m and up. It will be completely removed otherwise.

Note that this might break stuff like querySelectoAll('[layout]'). The element at least needs to be tagged with an empty layout attribute then ;)