Why is drag & drop so much smoother when adding "overflow: auto"? - javascript

I am making a CMS for a website. In the CMS I want to make a drag/drop/select -able index.
Dragging and dropping on a placeholder was not really smooth. But after I added overflow: auto to the div's where you can drag/drop/select, it is way more smoother and easier to work with.
Can someone explain me why this is happening?
It only shows if you have many div's in your webpage. (Like in an almost finished website.)
This happens in Chrome and Firefox. (I didn't test it in other browsers.)
With overflow auto <-- smoother
Without overflow auto <-- It doesn't do what you want

You must think about the HTML elements. Every HTML element is wrapped within its own 'box'. For each box, you can set its CSS properties like height, width, margin, padding, and so on. Each box is designed to expand with its content, even when you give it a set height. This state is known as overflow: visible; and is the default for every element.
In your case, you are dragging elements within an element to another element. Let's break this down a little. Before we begin dragging, our element lives within another element, inheriting its properties as well. The child element will do its best to fit within the parent element. When we drag the child element, jQuery is allowing the child element to be free from the parent element, and it will no longer inherit the parent element's properties. The child element's content will now expand to its own CSS properties until you drag it into another parent element, at which point it will inherit the new parent's properties.
In the same sense that the child is affected by the parent, the parent can be affected by the child element as well. After all, its default is overflow: visible; and wants to show all the content that is contained within it. So if the parent is 100px in width and the child is 200px, the child will be visible for 100 px outside the parent's original size.
As designers want to contain our elements to a fixed size, whether it is a px value or % fraction based on the parent element, so we need a way to prevent child elements overflowing outside of our parent element. This is were CSS overflow: hidden;, scroll;, and and auto; comes into play. I do want to note that there are overflow-x and overflow-y properties, however, I won't cover them too much as they are self-explanatory. Overflow: hidden; will simply hide the content that would overflow outside the parent element. This option will give no scrollbars for the user to view the overflowed content. So Overflow: Scroll shows the scrolling bars so that the user can scroll and see hidden overflowed content within the parent element. This option will always show vertical and horizontal scrollbars. Note: This is why there are overflow-x and overflow-y properties, however with overflow: auto;, they are not necessary.
Overflow: auto; is the solution for having only the necessary scrollbars for the content, and as a bonus, if the content does not overflow, no scrollbars are shown. So when we look at your div.sortobject, without overflow: auto;, it will attempt to visually stretch out to fit it's child elements. When you begin to drag elements around, the potential parent divs are overflowing visually trying to resize both for the child element and the jQuery helper element, the element that shows the user where to drop content. Setting overflow: auto; will cause the parent element to always retain its set width and height, so that when you drag your child element, it will appear smoothly as no potential parent elements are resizing. jQuery loves to calculate current exact dimensions of the elements it affects, and will also improve the animation as well.
I hope this gave some insight.

The default value for overflow is "visible", meaning that the overflow is not clipped. It renders outside the element's box.
The value auto means that if overflow is clipped, a scroll-bar should be added to see the rest of the content.
The smoothness effect that you refer to is simple that in default overflow, rendering outside the element's box will probably be slower/jumpier than when set to auto which moves the rendering into the actual element. This was especially noticeable for me in firefox looking at your fiddle example after moving all the elements to one column then trying to move them back.
Surprisingly in IE11, there was no noticeable difference between auto/default that I could see.
Please Read: Official W3 Documentation for Visual Effects

In the overflow-auto, I noticed there is a horizontal scroll bar in some of your boxes. If you take off any overflow, the div width will expand due to the content contained within them. When you get fatter divs, you'll get mixed div widths, and can cause quirky div placements when you drag them within a parent container. Think of a bucket with fat apples and small apples, versus a bucket with apples of all the same size; the position of the apples will be scrunched up differently between the two.
Bucket of fat apples with small apples: (div width of different sizes)
If you don't believe me that the div's are fat, you made the under lay of the divs the same size, but open up your link without the overflow = auto, you'll notice your images go over the right hand side of the border.
Bucket of apples of equal size (div width of same sizes)
With overflow set to auto, if you get beyond a certain width, the scroll bar will appear, and the width of the content will flow through, not changing the width of the div; so nothing gets quirky.

Related

How to display scrollbar in svg-pan-zoom?

I would like to know how can I enable the scrollbar while zooming with svg-pan-zoom.
I've tried overflow: auto on external div or svg tag with no luck.
Hopefully I can get some help here.
There is no way to have scrollbars by default inside of svg-pan-zoom as it's essentially an SVG, and inside of an SVG things behave like they're overflow: hidden. You'll have to implement scrollbars by yourself (render some elements that would look like scrollbars, compute their size and position...).
For anyone who comes across the problem, the best solution (hack) I've come up with is to set the container div to overflow: auto, set the svg element width and height to the width and height of the container div, set the position of the svg element to absolute, and then place a second div alongside the svg element. Then you need to synchronize size of the second div to the "true" size of the svg which you can get by calling getBBox() on the svg element, plus any scaling you have incurred by zooming. Thus the second div forces the containing div to have scroll bars. Similarly you need to synchronize the pan events with the scrollbars of the container, and vice versa.
When everything is said and done, panning and zooming happens through svg transformations that are synchronized with the scroll bars of the parent div, and happens completely transparently to the user.

How to get widths with different criterias in javascript

I am trying to learn and make a reference for myself but i can't find correct, enough, and not so confusing information. So tell me how to find the width of these..
Assume there is DOM element with 10px padding all around, border 5px all around, margin 30 px all around, and content that is too long for it so has scroll bars.
Find widths using javascript...
upto Margin.
upto Border.
Inside Border Padding and plus vertical scroll bar if present.
upto padding excluding vertical scrollbar if present.
upto content only that is visible. (no scrollBar, padding, border, margin, extra content)
upto content that's visible and hidden in scrollable area and with padding
upto content that's visible and hidden in scrollable area and with out padding
Javascript as too many unintuitive catches so please make it clear once and for all.
So far I have gotten this:
unknown
element.offsetWidth
unknown
element.clientWidth
unknown ( css width ?)
element.scrollWidth (see below)
unknown
only workarounds that i know are using lots of javascript to get computed values and then calculate all of these manually..but maybe there are builtin functions or better way to find things.
more Problems:
scrollWidth includes only left padding..shouldn't it either include both or none or at least have other options that do. LINK
box Sizing to border box changes the whole world and every question above needs to be answered again for that. For example for 5 css width property won't be true anymore.
There is no one function that will solve what you're asking for.
.outerWidth() will give the the size of an element, padding, borders, contained content and all. It will not however give you the margin of the element. Using the .outerWidth(true) parameter will give you the width of the element including the margin.
.innerWidth() will give you the width of the element. It is the total width of the content in the element plus the padding, but not the border,
If for some reason you want to know the difference between the inner and outer widths. Which is pretty much the border width or the difference between the edge of the border and the margins just subtract them from one another.
$widthDif = outerWidth(."Somethng") - .innerWidth('.something');
The inner and outer width function are mirrored and work the exact same for height.
Generally if you use .innerWidth() on something like the main body element it returns the width of the document minus the scroll bar because the scroll-bar is not part of the content view port.
Inside of an element is another story.
Best thing I could find in a google search was another StackOverflow question. Which outline rendering and element to 100% width inside of the scrollable element, getting its width and then deleting the element since it is unneeded. Getting the height of something minus a horizontal scrollbar could be found the same way. However once you have a vertical and horizontal scrollbar at the same time things could/would get complicated because the 100% height or width element could expand beyond what is in the view-able space depending on how the content is rendered into the element with the scrollbars.

DOM elements with overflow hidden and child elements within them, can the DOM measure the height/width?

I am working on a slider of sorts, and I am having a bit of trouble calculating the height and width of some children elements that fall outside of the defined area of the parent block element. They are in the hidden area of it in a matter of speaking.
So I am trying to figure out if elements in that void suffer a similar fate to elements styled with display:none where the javascript running with the DOM can't detect the height or width of them even if styled with a height and width, it treats it as if the element didn't exist for the most part in that aspect. Elements that are currently in my hidden void are not styled with display:none.
So, is it maybe something I doing or is it that they do suffer that fate?
I believe elements inside a parent with overflow: hidden are still rendered completely and have detectable, accurate dimensions - even when they do overflow their parents. Here's a fiddle to that effect.
There may be some cases where this is not true. If so, then it is dependent on styling.

Overflow stops working when z-index is changed

I have a container div with overflow:hidden wrapping a bunch of smaller divisions. They all have z-index: 1 including the container. All are positioned fixed.
When I change the size of the smaller divisions, overflow works fine and clips the smaller divisions that would exceed the container's boundary (fig. 1).
With jQuery, I change the z-index of the container to bring it forward, and everyone follows except that the container's overflow stops working. The inner divs overflow. (fig. 2)
Link to screencap.
And when I return the container to z-index:1, it and its children go back behind the other page elements where they should be. No problem with z-index.
Except that overflow remains broken. (fig. 3)
I've tried directly re-issuing an overflow:hidden to the container, using classes to set overflow and z-index, and nothing seems to work. Has anyone encountered something like this?
Edit: This only happens in Chrome - all work fine in Safari - not Moz-proof yet.
Make the children position: absolute, but keep the parent position: fixed. The children will stay put when you scroll, but it will allow the parent's overlow: hidden property to clip the children out of view.

How do you center floated element that overflow?

So I have a large amount of floated elements inside of a container with an overflow setting of auto. These elements (depending on screen-size) will almost always overflow to the next line as they should, however, I want to be able to center the parent div so these elements will always be centered in the page. The container is 100% of the screen width.
Oh, and to make things interesting: the size of the floated elements... is subject to change.
Here's what I'm referring to.
There's a lot of great solutions out there that I've found that have to deal with a single row of floated elements, but I'm almost never going to be dealing with that few items. I will overflow to the next line practically every time, which is why those methods don't work.
Would I be best inserting clear divs every few elements, setting the width and centering the container, or is there a better way to do this without Javascript? Thanks for any and all help!
You should be able to fix this with CSS. Put a width on your container div, and add a margin: 0 auto; to it. I found on your page it works well with a width of 1000px. The problem is if you use a width of 100%, you can't control how many of your floating divs will fit in one row, and when it will wrap because you don't know the viwer's window size. If you set a fixed width you have control over how many boxes will fit in each row.

Categories

Resources