简体   繁体   中英

responsive web design for n columns of random height portlets

Briefly:

How do I lay out N columns of random height portlets all in CSS so that if the browser is resized, the number of is columns reduced (using @media (min-width:)) and the portlets still sit nicely together on the page with no gaps.

This is similar to Float multiple fixed-width / varible-height boxes into 2 columns but more general.

Detail:

I've built a web application (PHP / Zend Framework) with a "dashboard" page made of a series of portlets. The portlets can be arranged in 1, 2, 3 or 4 equal width columns (user selectable) in a fluid layout. When the user resizes the browser window, the columns expand to fill the available width and the portlets also expand horizontally. The vertical height of each portlet is defined by its content. Some are only 1-2 lines, others can be 30-40+ lines of text / tables / image etc.

I want to turn this into a "responsive design" so that the user doesn't have to select the number of columns. On a small screen (eg iPhone) only one column will display. On a wide screen they might have 4 or 5 columns. If the browser window is resized, the number of columns will adjust up or down to allow portlets to stay approx 300-400 pixels wide.

I think I can do this with a bit of jQuery and some server side support (PHP), but would prefer to do it all in CSS if possible (no / minimal javascript).

Use a combination of media queries and text alignment to achieve this:

In its natural state, 'text-align: justify' will not work unless the contents of the line are long enough to cause a line-break. Otherwise, the text remains left aligned. We can solve this problem by giving 100% width to an invisible inline element at the end of the line.

Because 'text-align: justify' is designed to work on individual inline words, it works on any inline element—and more importantly any inline-block element.

To account for any and all possible numbers of elements on the last row, the number of “placeholder” elements you will need to add is equal to the maximum number of elements per row, minus 2. These elements should be inserted at the end of your grid (before the “break” element if you are not using a pseudo-element to break the row) and then left alone. Since they do not occupy any vertical space, the “placeholder” elements won't affect the layout if the last row is full or if your site is responsive and the number of elements per row changes. As long as you have enough placeholders for the widest view, you'll be fine.

Obviously, this has some semantic implications—as there is no way to create any of these placeholders using pseudo-elements. On a grid where the last row will always have the maximum number of elements, we don't need to use placeholders at all (just a break), but in most CMS situations they are necessary, and should be hard-coded into your HTML.

By simply applying 'text-align: justify' to the container, and giving the child elements 'display: inline-block' and a percentage width, you'll never have to deal with horizontal margins ever again! (Oh and did I mention, when using this trick, you'll also never need to use float on your elements ever again, so you can wave goodbye to those ignominious clearfixes and clear divs too!)

We should be aware that when using 'display: inline-block', our elements will be at the mercy of various typographic CSS properties, including font-size, line-height, vertical-align and word-spacing. These properties will have a visible affect on your layout's whitespace, but can be easily adjusted or removed as needed. In 99% of cases, setting 'font-size: 0.1px;' to the container and 'vertical-align: top' to the child elements should do the trick.

References

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM