I have a layout of boxes that are all floated left and when you click on their headings, they slide open revealing content. The issue is that the way floats work, when you click to expand one of them, it messes with the row underneath.
http://jsfiddle.net/FCCye/ <-- click on one of the headings to see the issue.
I've solved this by separating them into columns like so:
http://jsfiddle.net/caW4M/
That works fine, however, the layout needs to be responsive, so when the window is 480 or lower, it needs to be 1 column. Between 480 and 768 it needs to be 2 columns. Anything above 768, 3 columns. (obviously, the jsfiddles don't show the breakpoints I have set up.)
This is the code I've come up with to solve this, however it is not working at all. I was wondering if someone could tell me what I'm doing wrong.
// Create all three portfolio columns
var one = $('<div/>').addClass('column').addClass('one');
var two = $('<div/>').addClass('column').addClass('two');
var three = $('<div/>').addClass('column').addClass('three');
// Store all portfolio elements into variables once they're in columns
var colElems = $('.column .project');
// Now append the columns
var winWidth = $(window).width();
if ( winWidth > 480 && winWidth <= 768 ) {
// Remove everything from columns and delete existing columns
$(colElems).appendTo('#portfolio .content');
$('#portfolio .content').remove(one,two,three);
// Store portfolio elements into variables for safe-keeping
var c1Elems = $('.project:nth-child(2n+1)');
var c2Elems = $('.project:nth-child(2n+2)');
// Perform appends into portfolio columns
c1Elems.appendTo(one);
c2Elems.appendTo(two);
// Append portfolio elements to columns
$('#portfolio .content').append(one,two);
}else{
// Remove everything from columns and delete existing columns
$(colElems).appendTo('#portfolio .content');
$('#portfolio .content').remove(one,two,three);
// Store portfolio elements into variables for safe-keeping
var c1Elems = $('.project:nth-child(3n+1)');
var c2Elems = $('.project:nth-child(3n+2)');
var c3Elems = $('.project:nth-child(3n+3)');
// Perform appends into portfolio columns
c1Elems.appendTo(one);
c2Elems.appendTo(two);
c3Elems.appendTo(three);
$('#portfolio .content').append(one,two,three);
}
So, what I'm trying to do is append the normal 3 columns when it's not between 480 and 768 (because on mobile size, the columns would stack on top of each other anyway) and when between 480 and 768, only append two columns. So my thought is that at the different sizes, I would have to pull all of the boxes out of the columns, delete the columns, and reappend the columns in different numbers based on the window width. This has proved to be a failed attempt, so if anyone can explain to me what I'm doing wrong I would be very appreciative!
Thanks!
Not an answer to your question, but if you will follow the advice then your question will no longer be of interest. ;-)
First of all why don't you use CSS3 Media Queries for your different layouts? That is what they are for.
Secondly it is "bad practice" to use pixel values (or any other kind of absolute units) for defining breakpoints, even if a lot of authors actually do! It is best to only use relative units like 'em'.
The new Flexbox module could also be an option for you, depending on the supported Browser versions (especially IE 8).
And why don't you let the expanded box not simply overlap the other content by using 'position: absolute'?
Well, doing things with Javascript which should be done with pure CSS isn't a good idea. What happens, when JS is deactivated? And also from a performance point of view, on resizing the viewport ... - all bad.
So my advice would be to completely rethink your approach.
Related
Good morning,
I'm currently trying to implement an image gallery based upon the new CSS grid. In detail, I only want to display one row initially and let the user then expand more and more images by clicking a Show more button.
This is how it looks so far: https://stackblitz.com/edit/angular-96bdii?file=src%2Fapp%2Fgallery.component.ts
Now, my problem is that real-world images (instead of colored divs) need more time to be loaded completely. Therefore, the ngViewAfterInit hack doesn't work as the total width is not correct at the time ngViewAfterInit is called. Also, the total width is automatically calculated by a flexbox layout so I essentially don't know it (early).
Could you imagine a better (working) solution that perhaps uses CSS grid techniques I'm not aware of to limit the number of rows to one?
Kind regards
You could retrieve your images programmatically like this:
var img = new Image();
img.onload = function() {
//retrieve this.width
}
img.src = 'http://www.example.com/image.gif';
Then use it to compute the right width and photosPerRow
I've a requirement where I have 3 panels(Chats, Groups, Channels) in the left side panel and I need to adjust their heights based on the resolutions and also the items in that panels.
I will make api calls and get the items for that panels and bind them through angular bindings.
Please check the JSFiddle I've prepared for a clear understanding.In this, I've also wrote some additional media queries and adjusted the max-heights for the resolutions.
Now, My actual requirement is :
1) If there are no items at all in all the 3 panels, then all panels should collapse which is already working.
2) If all the 3 panels has items more than its size, then scroll should appear as the output screen which is already working.
3) If only one panel has items, then it should automatically expand its size like shown in the image in the
and same should apply to other panels as well.
4) Finally, if only few items are available in the 2 panels and more items are present in the 3rd panel, then it should show in the following way.
Actually, I thought of writing some jquery after the api calls based on the items count but that's kind of getting hard because I need to check the resolutions as well and also the items count in all the panels.
Is there any css way of achieving this?
at least, is there any article or something where I can follow and do this?
is jquery, the only way of doing this?
You could standardise it at 33.33333vh height then modify it using jQuery after the fact. It could get a little complex depending on how many exceptions you want to cater for but this unit will take care of the resolution differences and is supported by modern browsers.
In your jQuery you could work out the number of items in each panel as a percentage of the total and give each panel an appropriate height in vh - the label.
$(function() {
var totalNumItems = $('.panel div').length;
$('.panel').each(function() {
setPanelHeight($(this));
});
function setPanelHeight(panel) {
var numItems = panel.find('div').length,
heightPercentage = (numItems / totalNumItems) * 100;
/* calc -1.5em takes the label height into account */
panel.css('height', 'calc(' + heightPercentage + 'vh - 1.5em)');
panel.niceScroll();
}
});
If there were no items in a panel, it would calculate its vh as 0 and as such collapse it.
Edit: jsfiddle: https://jsfiddle.net/mattBBP/8vvcub3c/
This doesn't quite work because the area it's being displayed is not 100% of the viewport but this could be modified/offset / would not be a problem out of the fiddle.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I am trying to use https://github.com/Sam152/Javascript-Equal-Height-Responsive-Rows java script plugin to achieve equal row heights on my article rows of responsive grid on http://www.snapchamp.com. The plug-in is rendering some pages ok but in some cases it's messing the margins between element like below:
Plugin fails when I zoom the browser window and also when I turn the orientation of ipad or mobile devices. In mobile even with single element grid the margin go messy.
So my question are:
1) Is there a better js plug-in that achieves better results?like http://brm.io/jquery-match-height/ or something else that you used in past.
2) What is order of page css rendering and javascript execution? What can be reason for such grid margin issues?
3) I tried searching for zoom events on browser and answers were almost 3-5 years old. Wonder if we have any new event that notifies javascript of zoom event on browser.
I put together this simple bit of js/jQuery for you to perhaps use as a solution.
The fiddle.
jQuery(document).ready(function(){
//Find max height:
var maxH = 0;
var containers = jQuery("div.container");
var i = 0;
containers.each(function() {
var h = jQuery(this).height();
if(h > maxH)
maxH = h;
i += 1;
if(i == containers.length)
updateContainerHeight();
});
function updateContainerHeight()
{
if(typeof maxH == 'undefined' || typeof maxH == 'null')
return;
containers.css({'height': maxH + 'px'});
}
});
What it does is iterate through all of the container elements, measure them, and if the current element is higher than the previously highest element, it replaces the maxH variable. Once all containers have been reviewed, a function is fired to change all element heights to the highest.
This shouldn't affect your responsive as it doesn't care about width or how many units are in a row. A more sophisticated solution would only compare those in a single row, and you can check that by seeing how wide the parent element and how wide the containers are, then divide to determine in the current responsive layout how many columns are desired for each row and adjust from there.
I hope this helps give you some direction.
I realized that most solution dealing with javascripts involved changes with heights. If you look at the dom on site, you will realize that under article we had another element named entry. I was trying to make article of equal height but after reviewing code I realized I could even make a child element of same height. I switched from article to entry and my problem resolved to certain extent. Then once in a while re-sizing I was again getting margin squishing problem. After some time realization came that my theme is using masonry plugin and may be that is causing problem/conflict. I removed masonry and site looks better. Still need to test fully on different devices and different scenarios to test if site works.
Want to take this opportunity to Thanks #practically for effort and help provided. His solution provided also will work but will provide highest height to all elements across rows. The plugin ( https://github.com/Sam152/Javascript-Equal-Height-Responsive-Rows) works on rows wise height but is little slow to update the site and cause a bit of flicker.
I have a list of tags that are in a box that I've specified as having multiple columns:
#tags {
-webkit-columns: 140px 5;
}
Result:
The content of this list is dynamically generated.
When I resize the browser window, the number of columns collapses. e.g.:
Using jQuery / JS / CSS / etc., how can I determine how many columns are being displayed at any given time?
Unless you specified all column width-related properties browsers will try to fit whole number of columns in content area (between left and right padding of element). So (contentWidth + columnGap)/(columnWidth + columnGap) rounded down will give you result.
Note that right padding may be set so high that whole column will be able to fit there - you may need to adjust computations.
You can also directly get size of column if you have an element with 100% width inside columns text.
You can get the value like this:
$('#tags').css('-webkit-column-count');
Try alerting this:
alert($('#tags').css('-webkit-column-count'));
Similar to Alexei's answer, I figured out a solution to get the column count:
var $tags = $("#tags"),
column_width = $tags.children(':first').width(),
container_width = $tags.width(),
column_count = Math.floor(container_width / column_width); // in my case, sum of column gaps is less than the width of a column, so I can round down.
I have table with multiple rows, showing items for sale. When the user clicks on a row, a Javascript inserts / shows a new row right beneath it with details about the item. The issue is when the description is long, it forces the column widths to readjust / resize. This shifts the columns positions and is really annoying, especially for the user. Right now, I have my table.style.tableLayout: auto. I actually prefer it this way, because the columns are adjusted to the content.
My question is: how do I dynamically "lock" the widths of the columns in my table so that when I insert / show the new row, the columns do not readjust / resize?
I've tried:
dynamically setting the table to temporarily "tableLayout: fixed"
inserting / showing my new row
changing the table back to "tableLayout: auto"
Actions 1 & 2 works in in FireFox, but not in Safari and IE (6 & 7). However, doing all three seems to prevent the columns from shifting too much.
The frustration is unbearable ... loosing lots of sleep ... please help!
Thanks.
For those looking for the code (this is done in jQuery). This also assumes the first row has the proper widths for each cell. Pretty easy changes if needed.
$('table.class_of_table_to_fix tr:first td').each(function() {
$(this).css({'width': $(this).width()+"px"});
});
I would set a percent width on each column simply as a guide. Set it just once on the TH of each column. The browser will still adjust the columns to content if necessary, but the columns will stay in place more consistently.
Next, I would never put css "white-space:nowrap" anywhere on that table. A long description should not break the table layout, it should wrap around properly on multiple lines, and be readable if you set the widths on each column to suit the type of data. Similarly I would keep the use of (non breakable spaces) to dates, times and numbers and allow the text to wrap.
Other than that, I do this at my job on a dialy basis, and there's a time when you need to stop ulling hairs asking the browser to do something it's not designed to do. Content should flow and adapt. Locking column widths to pixels is 99.99999% of the time a bad idea.
PS: If you really, reeally, REALLY need to lock columns, the only solution I'm aware of that works with CSS2 and accross all browsers is to use images. You could insert a 1px high transparent gif image in each column, and counting in the padding of the cells (TD), set a pixel width on each image (IMG), instead of on the columns (TH/TD). You could hide those in the TH for example. You can leave the images at 1 pixel wide and set percent widths on TDs, and when you open a new row, you would get each column width minus TD Padding, and set that to the corresponding IMG. I haven't tried! I just know that in many projects I've worked on, I've used small gif images to lock a minimum vertical spacing between columns, for example.
I had a similar problem when I was implementing a table with groups that could be toggled. I wanted the initial ratio between the columns to stay the same without fixing the widths of the columns. By default the browser would change the widths depending on the visibility of the table's rows, which was undesirable.
I went ahead and followed #faB's suggestion of applying percentages, but doing so using a small script that would calculate the percentages of the th elements and apply them after the initial render. This made my columns stay the same width, even with all rows hidden.
Here's the script, which uses jQuery:
(function($){
var lock_widths = function() {
var total_width = $('table').innerWidth();
var headers = $('table th');
var leftover = 100;
$.each(headers, function(ix, el) {
var header = $(el), width;
// on the last call use the leftover percentage
if (ix == headers.length - 1) {
width = leftover;
} else {
leftover -= width = header.outerWidth() / total_width * 100;
}
header.css({'width': width + '%'});
});
};
$(document).ready(lock_widths);
})(jQuery);
Tested in IE7+, Firefox and Chrome. This works for my special case because I have header columns as a reference, but it could be rewritten to measure some other columns.
You can display the details of the row beneath the clicked one in DIV and set its
style="overflow:auto";
so that details will wrap and scrollbar will be available to display entire text.
I don´t know if you´re familiar with jquery, but that´s what I would use - in combination with a separate class for the column that´s causing resizing in the new row - to:
Calculate / get the with of the column
Set the with of the afore mentioned class
Add the row
I haven´t tried it, but that should do it.
By the way, there are probably other ways to do it, I´m just more familiar with jquery (for point 1. and 2.).