I decided to use a card UI in a project and checked a few Masonry-like libraries, it seems that all of these use position: absolute for arranging elements.
IMO this method is not the right tool for some purposes, for example my cards are expand/collapsible (like Google plus post comments) and although this can be animated in Masonry, it causes complete rearrangement in elements (it doesn't simply push elements down, elements jump from column to column).
I took a look at G+'s markup, they dynamically insert 1, 2 or 3 DIVs as columns depending on screen width (for responsiveness) then fill this columns with elements. In this way elements have their normal position and behavior, so if you need to add, remove or expand/collapse just insert the element into the DOM or change the height and browser does the positioning.
They also take care of overall height, so in the next Ajax loading, it calculates and distributes elements in columns in a way that columns height grow at nearly same total height (just like Masonry)
Do they use any specific library?
Is there any responsive framework/library that work in similar way?
I had the exact same problem and I think Salvattore is exactly what you are looking for.
It automatically creates some columns and puts all your grid elements into the right column.
The styling is then totally up to you, so no need for any position:absolute.
In fact thats all the styling you need:
.size-1of3 {
width: 33.333%;
}
Check it out: http://salvattore.com
Related
Howdy,
Context:
I am attempting to recreate a section which has required some complex use of grid layouts. In an effort to conjoin the grids and get a mobile responsive layout using grid areas, I have attempted to set some of the grid layout sizing across these grids using dynamically adjusting "grid-template-rows" style assignments in my JavaScript file.
The basic construction is that the elements should appear in a row together and should have a uniform height set by their tallest pseudo sibling, despite being in separate grids by necessity for layout purposes.
I set the various grid item elements into a "row" array which is looped through to create a new array of their heights, which is again looped through to find the tallest height among them. I then do this for each row and take the heights given and set all grid-template-rows style for the multiple grid parents using those variables as fixed heights.
I am console logging the heights at several points to cross check them. The grid style changes have a media query screen size conditional statement wrapping them to account for variations in layout at mobile view.
I then created a ResizeObserver for the body element which should in theory dynamically adjust the heights as the window resizes.
Broken Features:
The heights logged by offset-height of my div element variables don't seem to match up with the value of the sum of my element content height plus it's padding.
On desktop it seems to be overvaluing, creating white space below as though the tallest element is actually slightly taller, while at mobile it is cutting short and bleeding over it's assigned grid height which itself is too small relative to the heights of their contents.
In the Dev tools adjusting the grid height of the mobile row doesn't seem to create more space for some reason, though I'm not sure where the constraint causing overflow is coming from if not the grid row height. I need to understand this part for this to be a viable solution.
My ResizeObserver is also not working as intended. Likely because I have not configured it correctly or because I have not appropriately repopulated the variable values with updated figures. I'm not familiar enough with it specifically to know what all is broken.
I'm in dire need of a consult.
Suggestions welcome
GitHub:
https://github.com/Aces-Gambit/grid-chart-project
Alright here is my dilemma. I have a bunch of divs with the same width
(but variable heights). I want them to be displayed on the page one on top of the next UNTIL the bottom of the page, if there is space for a second column of these items on the page without scrolling then I want it to continue in the second column, third column, etc. If there is no available space left on the page then it goes off the page requiring a scrollbar to see things underneath.
This would essentially be akin to having float:top if it existed (which it sadly doesn't). Also I want this to change dynamically with the window size. If I shrink my window to one column width I want the data to go straight down one column. If I resize to two columns wide then it divides the data between the two columns.
Lastly the order of the divs MUST be preserved. I am willing to use jQuery and CSS including CSS3 to do this, anything else and I will have to look at it. I am sure that if I worked at it I could write some custom jQuery script to do this but I can't help but feel like it should be easier. I have looked at css3 columns but couldn't get them to do what I want so if they can do it the be specific as to how they do it.
Have you heard of media queries? At specific break points you can apply different CSS rules, so you could change the layout of your columns.
Have a read.
While working on a large list of tabular data that needs an easy sorting/filtering system, I discovered the Isotope library, which seems to do exactly what I want, and provides a lot of nice visuals and functionality. I'd like to be able to sort and filter table rows using Isotope, and I've come up with a basic demo that seems to work. However, a few bugs are present:
I'm using the <thead> section for filters and row headers, so I'm applying the Isotope selector to the <tbody>. However, when Isotope is initialized with the tbody as a container, the table cells in each row lose the width assigned by the table formatting. This isn't a huge deal, as I can set column widths manually if I need to, but it is rather annoying in the current context.
The rows are placed outside the table, in the top left of the table's container element. The relative positioning on the tbody element seems to not affect the rows' absolute position style rules (applied automatically by Isotope) as it would with a normal div. Normally, the absolute positioning would be relative to its container element if the container was positioned using either absolute or relative positioning, but this doesn't seem to be the case here.
The table rows are being filtered properly, and the Isotope library is properly applying animations and styling with those exceptions. If at all possible, I'd like to keep the use of tables, as the people maintaining this page will be doing so through a CMS, and don't know enough about HTML or the WYSIWYG editor the CMS uses to consistently produce any HTML structures beyond a fairly basic table. Does anyone have any advice on fixing these two issues? Thanks!
Edit: As an addendum, I've solved the initial problems I was having. Turns out, the tbody element does not accept a position: relative or position: absolute attribute, so the table rows were not being placed properly. Setting the whole table to position: relative solved the main placement issue, though the rows were then moved to the top left of the table. I solved this issue by offsetting the table row top attribute by the height of the thead element in Javascript, since without Javascript the display is normal.
This works beautifully in Firefox, Chrome, Opera, and Safari. However, IE 7, 8, and 9 all have rendering issues--and worse, they're all different rendering issues. IE9 refuses to place the table cells with the correct offset, IE8 doesn't show the rows at all, and IE7 seems to interpret the whole situation to mean "EXPLODE!". At least the main problem I encountered was solved!
I've integrated Wesley's style suggestions to implement Isortope -- a jQuery plugin using Isotope for table sorting.
It addresses things like the column width issue by automatically converting the table's generated column widths into inline styles. That way, the final table displays like the initial one.
Simple demo here.
Download here.
I have a large containing element with around ten DIVs inside - most are about 300px in width on average and are all set to float left. The end result is a widget/grid type layout. However, this style has been specifically built with responsive design in mind - we're using media queries to adjust the size and column count depending on device.
The issue is that we may have one or two boxes that are double-wide or double-tall. The double-wide doesn't really cause a problem with floating (that I can't solve anyway) but the issue is the double-tall. The double-tall would expand into the next row, but prevents other boxes from floating on the left of it. Float-right isn't an option because the tall box can't always be on the right.
I'm trying to find a way to dynamically figure out where each block can float to, like solving a puzzle. I've looked at a few javascripts like Masonry, jLayout, etc but they either don't work, or don't solve the problem of irregular boxes.
So:
I want to avoid absolutely positioning anything because we'd have to re-do that every time, for every element and they won't feel fluid.
I need to allow for double-wide and double-tall, but they may not always be present and eventually, users should be able to determine their location so we can't always just write javascript based on a known location.
I've tried moving around the elements via jQuery which does work, but has to be done on window resize, which is too much activity and results in elements flickering back and forth when you transition over the width that requires three columns to four.
Using css3 columns won't work because the DIVs are treated as text and are broken into two when they pass to the next column, and that doesn't allow for double-wide either.
Does anyone have any ideas or suggestions?
Use Jquery Masonry or Isotope, it'll arrange all the containers into the most space saving arrangement ( or if your using isotope, you can fiddle it around to prioritise other forms of arrangement)
Well, if you don't care too much about the order of your elements, a simple solution would be this:
Add your items to #main so that all .tall widgets are added first. Float .tall widgets to the right.
Likewise, make sure that all .wide widgets are added last and float these to the left.
It works in this case and I think will give you the most optimal use of space for any set of these elements.
I still have not found any real way to handle the situation. For now I've just written some custom javascript to swap around a few DIVs when the page resizes.
Is it possible to programatically access a Div's scrollbar handle and change its size?
--Edit: Is there a mootools plugin for something like this?
I'm trying to implement a lazy pagination mechanism, where a div's content will be updated onscroll, but I'd like the handle on the scrollbar to show the final size. Meaning, if there will be only 10 elements in the div, the handle will be rather large, and if there will be 1000, the handle will be as small as possible, even if the user hasn't loaded all the 1000 elements yet.
I found this site, but I want to avoid using this class.
Thanks!
You would have to use a custom solution for something like this. You won't be able to change the actual native scrollbar height. The plugin you referenced is more along the lines of the route you need to go to acheive the desired results.
Another solution you could implement would be to show the number of results via some other visual method, and not the scrollbar. If you are showing 75 of 100 elements, you could make a fixed div span 75% across the screen.
You could put an empty div inside your scrolled element, and set its height dynamically to something proportional to the actual content size.
You don't get any interface to the scrollbar itself from JavaScript, but it sounds like you can certainly get what you want simply by making the scrolled content as tall as 1000 elements. To reduce the slowness of scripting a thousand items you could replace the above-and-below-the shown-items items with a single top and bottom margin of the same height as that many items, and catch the scroll event to fill in new items to replace them.