Justified blocks in a Susy grid - css

Susy is a great tool, but I feel I have come across a weakness with it. Let's say that I have three floated block elements in a "blocks" container:
The "block" element will be given a "span(4 of 12)"
<div class="blocks">
<div class="block">
//img and text
</div>
<div class="block">
//img and text
</div>
<div class="block">
//img and text
</div>
</div>
As I expand the window, the content inside the blocks gets too large for my liking, so I add a max-width to the "blocks" element. When the max-width is reached, I, unfortunately, find the blocks to be too close together... So I add a max-width to my "block" elements... but this screws up this floated layout as the third block will be floated right (last) and the first two will be floated left (causing increased space between the 2nd and 3rd elements with resize).
I am finding the best way to do this is by setting "text-align: justify" on my "blocks" container, and "display: inline-block" on my "block" elements. With this method, I can create a layout where my block elements stop growing at a certain point ("blocks" max-width reached), but then the space between them continues to increase (justified content).
To me this is a really nice and valuable layout. I've read of much praise by different people about both inline-block layouts and Susy. I was wondering whether Susy is limited in accomplishing such a layout.

Susy doesn't have shortcuts for creating inline-block layouts (because of the white-space problems they cause) — but the real power of Susy is the flexibility to do anything you want, using the supplied functions. You can do something like this:
.block {
display: inline-block;
margin: gutter(of 12);
max-width: 14em; // whatever you need
width: span(4 of 12);
}
The same idea would work with flexbox, which I find much more powerful than inline-block — and it gives you the space-between option, which would replace any need for explicit gutters or gutter-overrides.

Related

Flexbox grandchild overflowing grandparent's height

I have a flexbox in a side navigation that is overflowing it's granparent's height. The basic structure is:
<div class="holder">
<div class="block-item">content</div>
<div class="flex-nav">
<div class="flex-row"><img src="#"><img src="#"></div>
<div class="flex-row"><img src="#"><img src="#"></div>
<div class="flex-row"><img src="#"><img src="#"></div>
<div class="block-item">content</div>
<div>
.holder { height: 100vh;}
.block-item { display: block;}
.flex-nav { display: flex; flex-flow: column;}
.flex-row { flex: 1 1 0; display: flex;}
img { max-width: 100%;}
Somehow the flex-rows are not shrinking to fit their grandparent's 100vh. Instead, the images are going outside of the view port. From the articles I've read, I'm not sure if a grandchild takes into consideration it's grandparent's height restrictions, though I'm assuming it would. The actual code is slightly different and can be seen in the following codepen:
http://codepen.io/strasbal/pen/zNEMpj?editors=1100
However I'm not sure the exact specifications of Codepen's viewport, it may not show when changes are put into place, so the site url is http://www.webhosting-issues.com
I forked your pen.
Comments are included in the new pen that say /* NEW! */ to help you keep track of what changed, but, basically, since you had already set the height of the overall container at 100vh, I simply assigned a height in vh units to the header and footer that let them maintain the heights they already were, and then did the math to fill in the heights of other child elements.
Overall container is 100vh
Header logo and contact footer are 19vh each
That leaves 62vh for the middle section, made up of three rows
That's 20.666vh per row in the middle section
From there, just set explicit heights for the images and their wrapper links for the inner rows, and you’re was good to go.
One problem you run into is that the text in the links by the images can run out of their container on smaller screens. You could fix that by putting them inside spans and positioning them on top of the images, perhaps with a semi-transparent background.
Hope that works for you.

Make fluid-sized block stick to top corner and allow content flow around it, but remain below content at certain breakpoints.

I've created a codepen to demonstrate the effect and what I want to achieve. It's not that complicated a problem, but I'm not sure how to be more concise and direct.
http://codepen.io/anon/pen/KwoeqR
What I want is to have a variable-width block of text that, when flowing normally, is below a block of content. But, through breakpoints and media queries, becomes stuck to the top right corner of the content, and allows the content to flow around it.
It's very easy to achieve one-half of the equation, or the other. I can achieve a floating top-right aligned block with this:
CSS:
.floater {
float: right;
}
HTML:
<div class="floater"></div>
<p>A bunch of content text.</p>
But when, through a media query, the floater no longer floats, it sits above the content. It needs to sit below.
To make it sit below, I can just do this:
HTML:
<p>A bunch of content text.</p>
<div class="floater"></div>
But now it won't float properly - it does not stick to the top right corner.
Solutions I have tried:
Absolute positioning:
This might work if the block were a fixed width. Instead it is a variable width so I can't simply set margins on the content.
Flexbox:
A flex column reserves the space below it, instead of allowing other columns/content to flow into it. If there is a way to get a flex column to flow or float, that would work, but I have not found one.
I hope this makes sense. It sounds very particular and precise but it really is not. It's a simple layout problem that does not seem to have a simple answer, unless I am missing it!
You can use a combination of float, flex and media queries as below:
.floater{
float: right;
}
#media (max-width: 500px) {
.wrapper{
display: flex;
flex-direction: column;
}
.main{
order: 0;
}
.floater{
order: 1;
}
}
http://jsfiddle.net/og8s0rvr/
Here you can see that the floater is floated right until the window gets smaller than 500px. At that point it switches to a flex layout where the order of elements is changed via order.

bootstrap full width element height under row

I need an element to take the entire screen's width.
Thus, I put it under .row like so because .container adds 15 px padding, then .row takes it away to be full width again.
.container-fluid
.row
header
.col-xs-12
"content content content"
But when I inspect the header element, its height is 0.
How do I get it to automatically be the height of the contents of .col-xs-12 without hard-coding the pixel values or using javascript?
So a few things:
First of all, as per Bootstrap's docs, "only columns may be immediate children of rows." If you are going to add a header element, make it a parent element of the .row or the .container, or put it within the .col-xs-12.
All .col-xx-xx divs float left, so they are technically taken out of the page flow, which is why your header element has no height--the browser doesn't see its contents as affecting the flow of the page, so it doesn't believe it has a height. Using Bootstrap, you can add the .clearfix class to fix this, though I suggest making sure that you clean up your Bootstrap layout a bit first.
EDIT:
Also (and I suppose this should go without saying, but since your code is sparse -- and in haml?--, I want to make sure that it's true), if your .col-xs-12 has no content in it yet, you won't have a height because there's no minimum height set on a .col-xx-xx divs.
<div class="container-fluid">
<div class="header">
<div class="row">
<div class="col-xs-12">
CONTENT HERE
</div>
</div>
</div>
</div>
I hope this helps!

Floated block elements not to wrap when exceeding parent width

I would like to know if it is possible for block elements, floated in a direction, not to wrap when they exceed the width of the parent element.
That was the quick and short question, for a little more details and an example, please see below.
I have done some research about this and I have not found a definite answer of whether it is impossible or not and that is why I am looking for a definite answer here of whether this can be done or not.
And in the case that it is not possible, I would appreciate a quick explanation about it so that I can improve my understanding of how CSS works.
Please see the following example.
I have 1 "container" div and inside it I have 3 "row" divs. Let's say the "container" has a hypothetical width of 200px and each "row" has a hypothetical width 100px. These values are not specified in the css, they vary based on the content on the page.
Each "row" is floated to the left so that they appear horizontally.
<div class="container">
<div class="row">
Some text
</div>
<div class="row">
Some text
</div>
<div class="row">
Some text
</div>
</div>
.row {
float: left;
}
In this case, when the total width of the "rows" exceeds the width of the "container", is it possible for the "rows" not to wrap and to remain in a single horizontal line ?
Just to emphasize, I cannot specify an exact width for the "container" in the css because I want the layout dynamic in order to accommodate different content.
Thank you.
The behaviour you're looking for can be achieved by replacing float: left with display: inline-block, and having white-space: nowrap on the parent container.
See this fiddle: http://jsfiddle.net/XYzea/1/
Blocks inside the container are aligned side by side (like float) but their parent has no width specified. By the way, the wrapper encloses nested divs. inline-block works in all modern browsers except IE<8 in which is not possible to use that display property with any hack if the element is a natural block element
The only way I can think of is to have the container > wrapper > rows. The container can be dynamic in size and have overflow:hidden while the wrapper will keep the rows in a single line

How do nested vertical margin collapses work?

I am having a hard time grasping the concept of vertical margins collapsing in nested elements. I came an article at http://www.howtocreate.co.uk/tutorials/css/margincollapsing explaining how it works however am confused by its explanation. So in its example it cites that there are 2 elements as follows
<div style="margin-top:10px">
<div style="margin-top:20px">
A
</div>
</div>
Seeing that the inner div has a margin of 20px, that is what will be applied for the entire block of code. What confuses me is everything after that and not yet looking about issues with Internet Explorer 7. Would someone be able to explain it for a complete newbie to CSS in a simplified manner?
Two-ish rules to remember:
If margins touch, they collapse.
Nested items "snuggle" if only margin separates them.
Elements outside the "Flow" behave differently. That is, this behavior does not apply the same to floated, or position:fixed, or position:absolute elements.
So for this HTML (nested divs) :
<div id="outer">
<div id="inner">
A
</div>
</div>
and this initial CSS:
#outer {
margin-top:10px;
background:blue;
height: 100px;
}
#inner {
margin-top:20px;
background:red;
height: 33%;
width: 33%;
}
The margin collapses to the max of the touching margins and the nested div "snuggles" to the start of the container, like so: (See it at jsFiddle.)
But, the moment the two margins are separated -- by a border or by preceding content in the container, for example -- the margins no longer touch, so they no longer collapse.
EG, just a little, non-breaking white-space , like so:
<div id="outer">
<div id="inner">
A
</div>
</div>
kills the collapse : (See that at jsFiddle.)
Using a border, instead of leading text : (Fiddle)
A diagram may help:
In case it wasn't obvious: blue = outer div, red = inner div; I've drawn them with constant height and horizontal positioning. You can work out what happens if the height is fitted to the contents etc.
The "Before collapsing" column shows what you get if the margins aren't considered adjacent, e.g. if you draw the border of the blue/outer div; but if there is no border, then you get the "After collapsing" column. The top row switches the two margins around from the example, because I think the behaviour in this case is more intuitive; the bottom one shows the example at howtocreate and is consistent with the top row.
Two-ish rules to remember:
If margins touch, they collapse. Nested items "snuggle" if only margin separates them. Elements outside the "Flow" behave differently. That is, this behavior does not apply the same to floated, or position:fixed, or position:absolute elements.
Brock Adams is correct, but I also wanted to add that "overflow:hidden" can also prevent nested margins from collapsing.

Resources