Active-CSS / active-css

The epic event-driven browser language for UI with functionality in one-liner CSS. Over 100 incredible CSS commands for DOM manipulation, ajax, reactive variables, single-page application routing, and lots more. Could CSS be the JavaScript framework of the future?
https://activecss.org
Other
42 stars 7 forks source link

Resizer description (WIP) #242

Open dragontheory opened 2 years ago

dragontheory commented 2 years ago

Resizes one to many elements in a web UI.

Unorganized unvetted thoughts/ideas so far... (hope I can keep editing this after submission...)

This is one of very few UI "Holy Grails" features that if done right, would blow up the web development community... IMHO. The one other feature that immediately comes to mind is the much anticipated CSS relational pseudo class :has(); (https://developer.mozilla.org/en-US/docs/Web/CSS/:has). Which is not yet supported in any major browser as of 2022.03.21 except ([https://caniuse.com/?search=%3Ahas()](https://caniuse.com/?search=%3Ahas())).

REQS.

FEATURES : :

more to come...

bob2517 commented 2 years ago

Will be starting this after the imminent release of 2.10.0.

Some ideas on the initial syntax, which should cover the basics before we get into more advanced options. I'll do these first and then we'll be able to see where we are with the other options more clearly and know what's feasible. I'm not sure it will work with the built-in CSS grid commands yet, mainly because those settings are specifed in CSS and I don't know how flexible wiith JS manipulation that can get yet. The below functionality will be a good starting point so it can be tested out with the more advanced CSS grid type commands. This also gives basic functionality for the bare minimum requirements and would be the simplest possible initial syntax to give people a chance to implement it without having to study up for a year on how to use it (like I did with CSS grid / flex, and I still couldn't tell you anything about those without referring to the manual). Here we go:

resizer: left(element) right(element) splitter(element);
resizer: top(element) bottom(element) splitter(element);

"element" would be any selector that had a width and height that could be adjusted appropriately. That would be up to the developer to set the CSS for. The splitter element will not be able to be moved beyond the capabilities of the adjacent element. Eg. If the left div is only initially 50px wide, the splitter will only be able to be moved 50px to the left.

The splitter element can look like anything and be positioned anywhere, including sandwiched in between the two outer elements. Moving it horizontally or vertically will resize the two adjacent elements specifically by left & right, and top and bottom, respectively per the above commands.

"resizer" is just a working title. I thought maybe "border-resizer" would work, but then I realised that we will take a separate element for the resizer itself, so it's not directly related to CSS border. If implemented into CSS, it should definitely not be a part of the border command, because that doesn't leave a lot of flexibility for styling. There should always be a splitter element which can be made to look like anything. It could be an animated gif, for example, or even a vertical marquee tag.

I thought about have a default splitter element, which may be an option if the splitter is not specified in the command. I'll do the stuff above and have a think more about that, as it will add more complexity, as well as imposing a new element onto the page for it.

dragontheory commented 2 years ago

...simplest possible initial syntax to give people a chance to implement it without having to study up for a year on how to use it...

Agreed!

Going with the least power principal and for cross and future browser compatibility, it's usually better to let the browser do as much of the heavy lifting as possible. Also, I believe the "splitter" is a work around for not being able to manipulate the resize attribute.

So my first instinct was to see what I could do with what already existed in pure CSS. Then maybe enhance the parts that needed it with JS.

https://developer.mozilla.org/en-US/docs/Web/CSS/resize

The first good thing that I noticed is that resize can be applied to any element. Yay!

The first bad thing I noticed is that it can only be controlled at the corners. Boo!

As far as I can tell, there is no way, with just CSS, to change the size or placement of the resize control other than the corners.

It may be just the handle that is limiting.

So,

  1. can we take advantage of CSS resize and enhance the handle so it can be vertically and horizontally centered and or equal height or width of a DOM element sides via JS, without much work?

If so, I think that is a huge win by itself for DEVs in creating something that leverages existing functionality and more to your point, has virtually zero learning curve.

Then we see how else we can exploit the heck out of it using CSS attributes.

  1. The next thing may be seeing what the existing default behavior is for multiple resizers on a single page. If it doesn't work as expected, is there a quick JS fix for that?

  2. Trying a JS solution that emulates the best of what resize offers.

One of the most common JS solutions is to set inline widths rather than modern CSS attributes. Which works but is rather heavy handed. What happens to the inline width in a liquid layout? Or when a column, such as a sidebar, is dynamically added or removed? Both are very common scenarios.

CodePen example of setting col width inline. https://codepen.io/corvus-007/pen/wvrpGKX

CodePen showing funky behavior with multiple pure CSS resizers on a single page. https://codepen.io/jonathandavito/pen/JjONmwR

For reference, this script comes close. The DEV gets that relying on web standards to drive innovation, leaving the layout to the developer (non-opinionated), and using modern CSS attributes, allows for less coding and maximum flexibility.
https://split.js.org/#/split-grid

WDYT?

bob2517 commented 2 years ago

The limitation with the resize command is, as you say, the position of the resizing anchor. I can't change that specific functionality.

This is the problem - I can't change or enhance existing CSS commands. Remember, that's a CSS command that runs in the browser - it's not running in JavaScript. I can't change the way that command works. So that would be a request to the CSS boys and girls to get the resize command enhanced.

I could rewrite the resize command in JavaScript, and it would probably be very hacky. And It would completely bypass the CSS command itself, and we would lose browser optimization and also lose future compatibility if the command was enhanced by the W3C. So the only practical option is to code up a brand new solution.

So we either go with a brand new solution, or the request gets redirected to the W3C for an enhancement to the existing functionality, directly in CSS.

I can very easily code up a command that does the resizing feature as per the code editor used on the ACSS docs site (ie. like split.js). And it would work on all sides of a central element that had divs all around it. It would be able to handle massively complex scenarios. The basic elements are two container elements and one splitter. Adjusting other elements that require adjusting at the same time could be implemented with options in the command.

But I can't involve the CSS resize command in any way, and I can't get into changing the way CSS flex or grid works... It's just not possible.

bob2517 commented 2 years ago

Split.js is a good example of the simplicity of what needs to be done. It also gives good options that we can use.

Only 3 main elements are used there for the functionality. 2 containers, and 1 splitter. The splitter can contain sub elements to make it look fancy.

bob2517 commented 2 years ago

There's not actually a lot of code involved in split.js. I won't take any of this code though because I already have the code in the code editor ready to use. I just need to add things like the gutter option and stuff like that. Plus the ability to adjust other elements in addition to the 2 default containers - in the same way that the second CSS resize demo attempts to do.

dragontheory commented 2 years ago

Ok. Very good. That answers a lot of questions.

Agreed. Let's go with the next best thing than petitioning WHATWG themselves to change the CSS standard.

Yeah, I liked how the split.js author left the markup alone for the DEVs to do what they wanted and relied on the CSS standard. Helps to maximizes flexibility for DEVs and reduce complexity for us.

As long as it

  1. doesn't require added markup such as parent elements,
  2. leverages modern standard CSS syntax like Grid and measurements like rem, px, and auto, and
  3. works with multiple resizers/splitters on a single page...

It's all good! :)

bob2517 commented 2 years ago

Just a note on this for later. I can see it failing on grid when used vertically (and probably horizontally) unless the splitter is attached directly to its container. The reason being that you need to set the height/width/top/bottom/margin/whatever for the splitter to work, and grid appears to have a mind of its own and limits its own size to the number of rows. It would be weird to mess with that. The workaround would be to attach the splitter element to the grid's container. Maybe not - it may be fine. This is here as a reminder for when I get to it.