div in fluid grid jumps in size at breaking point - html

Code is too long to post, but essentially i have a couple divs/sections which are meant to be responsive via float-grid. They look like this:
<div class="col-4">
<section>
<img src="https://tf-assets-prod.s3.amazonaws.com/tf-curric/WEB-DEV-001/2.6.3_challenge_responsive_layout/rey_square.png" />
<b>Rey</b>
<p class="expl">xxxx</p>
</section>
</div>
At 745px (give or take) the 2nd row divvies up and pushes the first img all the way to the right and changes in height. My guess is that it has to do with the float, but i really can't change it.
Also, when dragging below 640px the first image appears fine, but the 2nd and all subsequent images show the title next to its image. What is causing this to happen and how do i fix it?
Repl.it

Since you cannot use flex, then you could fix this by using nth-child. The below will target the first item in every row for a 3 column layout, except for the first row which doesn't need this anyway
.col-4:nth-child(3n+1) {
clear: left;
}
I suggest you put this in a media query range so that it does not affect other width. If you don't put this inside a range, you might need to write extra css to override it later

Related

Elements in CSS Grid Column, top margin behaves as position top

Difficult to come up with a good title - by all means, change if you can.
Traditionally, a margin on an element can be used to move elements around a page relative to its previous elements. So, if I had a div as a column on my page I could shift elements vertically within that by setting their top-margin CSS property.
This is handy in dynamic pages where some elements might not exist according to given condition, eg, a very simple example here:
https://jsfiddle.net/jhartnoll/4s6pcLu0/1/
I have simply defined a column with a div element, positioned two other div elements and made one of them have a 2em vertical gap between it and its predecessor.
If you remove (or set Display:none) element #one then element #two is shifted up the column and positioned 2em from the top of the column, rather than 2em from element #one which is no longer there.
However, if I try to do a similar thing using a CSS grid, thus making the DOM tree simpler and more flexible, I run into a problem:
https://jsfiddle.net/jhartnoll/xvhycg0k/11/
In this case, the columns are set by the CSS grid so are sort of pseudo columns, but when I set my elements to have margin-top: 2em the margin is calculated from the top of the grid column, not relative to a predecessor element.
Therefore, if element #one is not present, #two simply remains 2em down from the top leaving a gap above...
This behaviour renders margin-top useless, because it is exactly interchangeable with top on relative positioned elements.
Is this a bug with CSS Grid, or am I using it wrong, or is there a way around this?
CSS Grid seems great, but I have run into several problems like this where dynamic content is concerned, if elements have potentially variable heights, or may not be there at all, the Grid leaves other elements floating in space, unable to shift up.
EDIT for clarity of the dynamic problem
Thanks for the comments so far. The problem is not with using the layout, I understand how to set up grids, and rows, define sizes, spaces, span etc, the problem is with dynamic content.
Supposing I have an extremely simple product page:
https://jsfiddle.net/jhartnoll/xvhycg0k/42/
Irrespective of the grid spacing, row/column size etc, the concept is simply that I have thrown in a "Price reduced by 10%" splash element above the product title.
Naturally, product pages would be using templates and therefore the HTML and CSS should be fixed and flexible enough to enable elements to be missing or present.
Not all product pages will display the 10% off deal, so on those pages, I would want the Product Title to shift up into the top element position.
This, as far as I can tell, cannot be achieved with grids.
Similarly, if there was a div which contained a product description and underneath it some product cross promotion or something, the description might be of variable length, so with the div as a column example in the my original question, the content would automatically expand the description grid and shift the cross promotion stuff down the page. Again, this can't be achieved with grids?
So, I was messing around with using a grid defining columns only and simply one row per page so that content could be stacked in columns similarly to the original div as a column example, but then I ran into this margin-top problem which, within a Grid is that margin-top is relative to the grid top, not to the elements above.
So I can't find a way of creating a dynamic website, using a template design which allows for conditional elements and variable element dimensions using Grid and without using Javascript to manipulate on page load.
In my mind, there should be an option for a row-shift property to allow elements to jump down a row if the content is too large, or jump up if there is nothing obstructing it... or something like that anyway!
Hey try the following code I guess it will help your requirement!
#column{display:grid;grid-row-gap: 10px;width:4em;height:auto;border:1px solid grey;}
#one{background:red;width:2em ; height:2em}
#two{background:blue;width:2em ; height:2em}
<div>
<div id="column">
<div id="one">
</div>
<div id="two">
</div>
</div>
</div>

Why does this CSS produce such a huge layout when displayed on a smartphone?

I have this CSS: https://cal-linux.com/styles/tutorial.css
And a sample page that uses it: https://cal-linux.com/tutorials/gswc++.html
When I display this on a smartphone (or when I check it through Google's Mobile friendliness verify service), the layout looks huge (badly cropped, instead of reduced to fit the smartphone's screen.
I only use proportional measures (for example, outsidecontainer's div has width 80%, inside right-most column has min-width 25%). I'm placing Google Ads in there, but it's a "Responsive" add, which is supposed to adapt to the page's available size and layout.
Any tips on this? I figured posting the actual links to the pages might be ideal; but please let me know if a "minimal" instance of code that reproduces the problem would be preferred.
Thanks,
Cal-linux
There are a few things I note here:
You use display:table-row and display:table-cell a bit too much. Those don't respond as well to the resizing especially if you have not specified the width of each item. Instead either use floats with a clear:both on the container's :after pseudo-element or inline-block. Either way you should define percent widths for the containers.
Your css has a lot of white-space:nowrap but doesn't use overflow:auto which forces the element to not resize the content and just stretch its parent container.
Aside from that a few places I see a fixed px width which makes it more difficult to resize. It doesn't seem to be your ads. Although google's script does throw an error about trying to put an ad in an 86px x undefined space. You can set a fixed height or at least a min-height to give the script an idea of how big an ad should be placed there.
The easiest solution is to incorporate bootstrap to do the heavy lifting of setting up a grid for what you want.
You can basically do your two column style like so:
<div class="container-fluid">
<div class="left-col col-md-11">
<!--- ALL YOUR CONTENT HERE //-->
</div>
<div class="right-col col-md-1">
<!---Google Ads go Here //-->
</div>
</div>
If you want to stick with your own style, by using the code inspector in chrome I was able to get to the following result when resized:
I made the tablerow class be a standard display:block
The first column was set to width:75%; display:inline-block;
The second column was set to width:25%; display:inline-block;
The autosize elements changed to display:block;max-width:100%; overflow:auto;width:auto;padding:0
The div.code blocks were changed to display:block;white-space:nowrap;width:auto;
Everything else stays the same pretty much. That should fix it, however you should note that frameworks like bootstrap help out with mobile sites by making the page columns collapse and go one ontop of another for mobile browsers so that they get maximum space.

Vertical alignment in column content in Bootstrap 3

I am trying to horizontally align 3 columns (Bootstrap) that have variable heights depending on the size of the view port. As seen on the first picture, everything is centered and aligned on large screens.
When the viewport becomes smaller, the paragraph's height changes and the alignment is lost. I would like to keep the headings (blue), paragraphs, and buttons aligned.
My inital thought was to create three rows for the three different types of elements. Unfortunately I will not be able to do that since I want to keep the border in the middle column.
What would be a correct way of keeping alignment of these three columns regardless of the viewport size?
I've never really seen a perfect answer to this, thats not with javascript, I can't remember the exact code, however, last time i did it, i placed the text in a nested section, each boxes text section had the same class, and i assigned a min-height to that class that was long enough that it fitted the longest piece of text in, then place the button underneath that section.
If you put your code in a JSFiddle i can help you more, however,
it should looks something like this, layout wise,
<div class="four columns">
<img></img>
<div class="text"> this will have a min height
</div>
<input>button here</input>
</div>
I hope this helps, i know it doesn't seem very clear, if you have a live version or a JSfiddle i'm more than happy to help further.
as for the text, you're very limited, there is some very good jquery scripts, just look through http://www.unheap.com
and just have general play with text sizes
Assuming they are in an inline containe vertical-align:middle;

How to create horizontal menu in fixed sized div with one link wider than the others

So my problem is this - I have a div with fixed size of 970px. Inside it I want to create a horizontal menu where the first element will be a link to the home page with the logo of the company and the others will be standard links to different parts of the page.
What I want is to make the link with the logo wider than the other links and let the other links occupy the space left equally. Due to the fact that in near future the width of the container div may be changed even though I know the number of links I would like to use percentages to determine their width so the width of one link will be = (width of the div - width of the logo link)/5 (the number of link I'll have.
I tried with something like this
<div id="main-container">
<div id="logo-container">
</div>
<div id="standard-menu-container">
</div>
</div>
But I couldn't make it work (In fact all this is wrapped in one other div that I haven't shown here). So googling about this I get to the understanding that maybe using some sort of table may solve my problem. To be honest I have never used table this way but I followed an example and I got this result : JSFiddle Example where the red rectangle is meant to be my Logo link and the problem is that everything else is stacking under. In this particular example the logo link is excluded from the <ul> but I played around with that case too and simply trying to set one width in pixels and other - in percentage seems to be not what I need to do.
I would appreciate any help, just bare in mind that I tried a lot of styling with divs and display: inline-block and it breaks other parts of my structure so I would prefer a solution where the normal flow is not disturbed (like using a table for example)
You're on the right lines with the display: table-cell. I've made a few changes where you had extra code that wasn't needed, and set the <ul> to display: table, rather than the container. Adding table-layout: fixed will make items in the list (the cells) occupy an equal width.
Then, float the logo left, don't specify a width for #main-menu-navigation because then it will fill remaining space, and give it margin-left: 150px to cater for width of logo.
So that won't make much sense when read. Take a look here:
http://jsfiddle.net/LREbC/1/
Try resizing, the cells will adapt to the width.
Note: When using table-cell you don't need to define a width, the behaviour is the same as actual table cells.

Prevent floated divs from wrapping to next line

Here is my site, first of all.
You'll notice that underneath the divider bar in the middle of the page, there are three columns, one with a form, one with text, one with links.
Now, resize the window to slightly smaller, and the right div will drop down to the next line.
Is there anyway to just not display that? So, the divs will adjust (I have a liquid layout) up to the point where they won't fit, then, instead of wrapping the div down to the next line, it just won't be displayed?
You can also achieve that with CSS only.
Just assign the following CSS attributes to #row4:
#row4 {
min-width:1202px; /* the exact value depends on the sum of the width of your 3 column boxes */
overflow:hidden;
}
This differs slightly from your intended solution, since the right box will stay partly visible when sizing down the window and will not immediately disappear completely.
Please be aware that min-width won't work in IE6. However, there are several ways to emulate the min-width property, if you need to support old IEs:
http://www.thecssninja.com/xhtml/ie6-min-width-solutions
You can give them a wrapper div with a min-width set and force it to use a horizontal scrollbar if it gets too small. The nice thing about a wrapper div is you can give it a max-width as well and keep things from getting wonky on super huge monitors.
I'm not a fan of horizontal scrollbars, but it beats completely removing content.
Ok here is what you should do
Wrap all three floated division on a parent div, something like this
<div id="parent">
<div class="form">......</div>
<div class="text">......</div>
<div class="links">.....</div>
</div>
Now to solve your problem give a fixed height to the parent div like
#parent { height:400px;clear:both; }
You would have to use Javascript to get the width of the viewport, then change the display property of the div that is wrapping to display:none so that it doesn't show up when the browser width is too small.