Tricky CSS vertical centering with padding - html

I have two columns of dynamic content, and want to align them as follows:
a) if the right column is small, I want it to be vertically centered
b) if the right column is large, I want it to be top aligned
c) the right column should always have (at least) 80px top padding.
See first and second image below for desired behavior.
Without c), this is trivial, eg one method is using flex with the second column having align-self:flex-start .
With c) it still appears trivial - just give the right column 80px top AND bottom padding to ensure it is centered, but extends down if it doesn't fit.
However, I do not want the extra 80px at the bottom when the content is large, as shown in the third image below, which makes things far more complex. I've tried a solution like having the right column its own flex container with flex-direction:column, using two 80px height divs with one set to flex-shrink:1 and the main content set to flex-shrink:0, in the hope that one 80px would collapse when unnecessary - but this simply doesn't work (the right column isn't restricted in height so never shrinks).
Any options? The use-case here is that the right column is dynamic text, but the obvious option of having 80px top and bottom results in either too large a gap to the next section of content when the text is long, or too short a gap if the text is short.

Related

Is it possible to use CSS flexbox to shrink/stretch content on both axes, vertically and horizontally?

It's my understanding that flexbox containers and their child items flex fully along only one axis, depending on the value of the flex-direction property, row or column. With a "row" container, you can stretch and shrink the width of the container and the individual boxes it contains, but the content in those boxes does not grow or shrink to match. On the other hand, resizing a window vertically does cause content to resize accordingly. (I think the situation is vice versa with "column" containers, though I haven't tried them alone.)
So my questions:
Do I have that right? I've read through many nice blog posts on flexboxes, but none covered this characteristic explicitly as a main 'feature.'
Is there a flexbox-only workaround, some arrangement of rows-inside-columns or the other way around, maybe with specific properties set special ways?
I tried putting a columnar container inside a flexbox belonging to a row container, and then putting text into that, but I saw no change in resizing behavior--the text still resizes only when the window/viewbox is resized vertically, not horizontally. See this codepen.
(About the example: first, I apologize for extraneous properties or properties set to random-ish values, but I was trying anything and everything. I tried to pare them back without messing up the demo but I'm sure there's much to improve. The svg logo on the left is just in a top-level flexbox in the main container for that row--it behaves as expected, shrinking/growing only with vertical window resizes. I put a hidden logo in a third box on the right so with equal-width boxes on either side, the text between them comes out centered in the viewbox, if you don't use shrink too much side to side. Maybe there's a less kludgy way with flexbox to a row with centered text and a logo on the left.)

How to make a column extend to push the columns below it over

I don't think I asked this as clearly as I could for easy searching, but here goes:
How can I make a bootstrap column extend to a larger height so that when the columns wrap around, they get offset by it even if it's not tall enough to cause that normally.
Essentially, how do I make the bottom panel in this bootply stay centered in both cases?
http://www.bootply.com/FCgrUtGuQ0
My left panel will be of variable length, which means that if I use a col-x-offset-x it will get pushed over further if the left panel extends below middle.
If I add the bottom panel to a new row then it will have whitespace above it if the panel left is longer than middle.
I tried the negative margin trick without success. It lets you change the background colour which those examples all used, but it doesn't seem to cause the floated panels to shift right.
I need this layout to behave differently at smaller screen sizes, so I can't just put the middle and bottom in the same col-x-6 as this is actually my lg layout, and at sm I need it to act with left at the top in a row, middle and right as two columns in the second row, and bottom as a third row.
Negative margin trick:
.row {
overflow:hidden;
}
#extend-down {
padding-bottom: 10000px;
margin-bottom: -10000px;
}
This isn't answering my own question directly, as it doesn't explain how to expand the column height to make the repositioning happen properly, and it's not generic to all column sizes and arrangements.
But in my exact case this arrangement of columns and rows case can be solved with two master columns and then separating the contents of the second, where 3-6-3 columns can easily be made to be 3-9(4-8) columns which maintain the same 3-6-3 spacing.
http://www.bootply.com/UTq2klEuCG
By putting the middle, right, and bottom in the second column then letting those wrap around naturally seems to handle all my cases with this specific layout.
So I went from
col-x-3
col-x-6
col-x-3
col-x-6
to
col-x-3
col-x-9
{
col-x-8
col-x-4
col-x-8
}
This isn't ideal, as a 2-8-2 arrangement might be best at a large screen size, but the math doesn't work to easily create a subset within the col-x-10 that would need that follows the same spacing as a 2-8-2.

CSS inline-block width issue

I have a page with a container div, this container div has two columns, both inline-blocks. One column (left Hand side (LHS)) is the ticbox selection for a shopping catalogue, the right column is the output of the chosen selection.
The issue I have is that each is assigned a width based on percentage of the parent width, the left - fixed column is 20% width, the right, output column is 79% width (I tend to allow 1% for variability) .
BUT: the left column needs a minimum width - defined in px as 155px;
The right hand side (RHS) column is filled with inline-blocks for each product displayed by the catalogue search. These blocks are fixed width (140px)
MY ISSUE:
When the page loads on my screen it's fine, but when:
LHS:
min-width:155px < width:20%
(the browser window is resized)
The whole of the right hand side drops below the content of the left hand side (as the width for it is less than the required 79%.
Some simple example:
Please note there is no borders or paddings to be considered when measuring widths.
HTML:
<div id="container">
<div class="leftsideMenu">Menu column.</div>
<div class="rightsideShop">Shop Contents</div>
</div>
CSS:
#container{
width:80% /* of screen */
min-width:555px; /*should leave 400px for shop contents */
}
.leftsideMenu {
display:inline-block;
width:20%;
min-width:155px;
vertical-align:top;
}
.rightsideShop{
display:inline-block;
width:79%;
max-width:calc(100% - 156px) !important; /* fix attempt - doesn't appear to work */
vertical-align:top;
}
[Some] ATTEMPTED FIXES (not in order of attempt):
1) Calc to make the max-width always less than 100%-155, doesn't appear to work
2) Floats and margins : this does work but presents the problem of layout that the client doesn't want shoes underneath the LHS column and float height = 100% parent is another issue,
3) I have also tried to use https://stackoverflow.com/a/6350781/3536236 answer to a similar question - with the approach of having the RHS relative and using a forced LHS margin but this doesn't work as the solution linked here didn't work for me in this situation.
4) I think flex-box style working is probably a best way forward but I do not know enough about it, and to be brutally honest, I was hoping to avoid a massive reworking of the page CSS. (I had originally expected this issue to be 30minutes!).
5) Setting no width (just max-width) for RHS - to auto defined width, this auto defines to 100% and goes underneath the left hand side column.
I think the answer is pretty simple but I can't see it :(.
To explain parts for the points above, the LHS was originally a float and that worked fine but the client wanted no products appearing underneath the menu in the LHS column, so I thought - ah simple, make it an inline Block....
Any help as to keeping the right hand side giving the left hand side the space it needs, even upon screen resizing?
............
OH FOR FFFFFFFF SAKE -- I have just written this all out, and while I've been writing this have been trying different ideas as they've occured and it's finally worked:
Now after all this effort for writing this out I want to post it anyway, but the Solution is below!!!
OH FOR FFFFFFFF SAKE -- I have just written this all out, and while I've been writing this have been trying different ideas as they've occured and it's finally worked:
For some reason my calc works with:
max-width:calc(100% - 160px); Giving a spare space of 5px .
Any ideas why this is so, as I say, within the container div standard widths are percentages and there is some padding in the product container (inline-blocks) inside the RHS, but this really shouldn't have influenced having to add more "padding" space in the calc method.
Anyway, it works now. I'm happy. Maybe this will help someone?
With inline-block you will have some whitespace taking up some space in your layout.
Two inline-block divs with a width of 400px in a container div of 800px won't always render next to each other.
You can fix this by making sure the closing tag of an element is directly next to the opening tag of the next element in the HTML (e.g. </div><div>, no newlines or spaces).
A better option is to apply font-size: 0 to the containing element and then reset the font-size to e.g. 1rem for the inline-block elements.

Centering floated, width-less divs with CSS

You can see what I'm going for at http://jsfiddle.net/vW45s/. A center div with two lines of text, and text on the left and right that abuts the text at the bottom of the center div.
I would like the text to be centered on the page (either the main "hello world" or the second line). Right now I'm using an outer div with a specified width and margin: auto. If the width is too large, the text will not appear to be centered; if the width is too small for the inner text, the divs will be stacked: http://jsfiddle.net/vW45s/1/.
Is there a better way to center these three floated divs, while still getting the left and right text to align with the second line of the center div?
Any tips would be appreciated. CSS is not my strong point, but I'm learning.
Floating and centering doesn't mix well. To be able to center something, the browser must be able to determine how wide the element is. To determine it's width, it needs to know how wide the other floating divs are. Their width depends on the width of the element you want to center.
You have these options:
Try to get it to work without assigning a size. It might be possible. Be ready to spend a day or two on this to get it work with Firefox and Chrome and then one week to fix it in IE. ;)
Assign a width to all three divs
Use absolute positioning instead of floating. Make the center column 100% wide and move the side columns in front of it (one left with left: 0 and the other right with right: 0; both will need a definite width). That works until you start resizing the browser window too much (and the side columns start to overlap with the center).
Use a table or display: table-cell because table cells know about their siblings widths without floating. That means you can assign a width to the two side columns and then let the inner column grow.
PS: Yes, I know about the myth that tables are bad. The myth is a gross simplification. It's bad to nest 500 tables to get the design you want if you can get the same result with two divs and some smart CSS. But that doesn't mean you must not use tables at all.
Have you tried adding width: 33% to the left, right, and center divs along with text-align: center?

CSS Layout Question

I have a reasonably complex layout problem:
I would like to have a main box that has 95% width and that has side margins all around (140px 2.5% 20px 2.5%).
Within that box I would like to have two columns:
The first should (left hand) should have a transparent background and will be mainly for links but also some other arbitrary block content (like poll results etc.). The menu in this bar is an unordered list and I would like it to highlight in such a way as to appear to join with the content when active (which means that the 2nd column must be at least as high as the menu is; thus equal height columns are an issue although, I don't mind using min-height and assuming that the menu will never be longer than, say, 400px). This column should be 180px (unless a percentage is absolutely vital; then just assume 30%)
The second column is the content column and should be padded in slightly from the main content holder but not from the left hand column (so that the links appear to join the content). I would like have rounded corners on this column which means that the standard faux column technique will not work because the rounding does not apply to it. (this column should take the rest of the available space inside the main div that is 95% wide)
I also like the idea of using rounded corners on the left hand side of the highlighting of the active menu item.
All this is going to have an absolutely positioned header above and if possible, I would prefer to use jquery's "corner" plugin to create rounded corners rather than images but I'm at a stage where it doesn't matter immensely.
The problem is that I've done each thing individually but not all together. IE generally mucks it up somehow. For example, the closest that I've come to doing it correctly, IE decided that although my menu bar was floated to the left, it shouldn't actually write any content horizontally in line with the menu and so although the box was there (I could see the background) the content was halfway down the page...
Sorry that this is so long and without code but it seems silly to give a pile of code to what seems like should be a trivial problem...
Here's what I managed to get working in standards compliant browsers:
alt text http://www.inselpix.com/img/24036931603.jpg
(I've never used this image host before, I hope it works...)
Check out the float tutorial.
This 2 column layout caters for IE deficiencies.
IE has problems with the float model (although apparently there's improvement in IE 8). You could try using just absolute positioning... even though that's probably not the ideal solution.
Thanks all, Katesmeow probably helped the most:
Turns out what I needed to do was absolutely position the main div and the left (menu) div (which I gave a minimum height) and then relatively position the content div. I made the left menu 18% wide with a 1% left margin and the content div I made 80% wide with a 1% right margin. I also had to add bottom padding to the main div according to the top offset that I gave to the content div (so I used "top: 30px" to give the main div padding from my content div and then used "padding-bottom: 60px" to compensate 30px for the top - because otherwise the div extends too far - and then add a further 30px of padding).
The problem is that IE still mucks it up; so while my main div is 95% wide, IE doesn't do the relative widths properly and my main content pane is too wide. So, I used conditional comments and set the content div to be 76% wide (95% x 80% = 76%) and it's working reasonably well. The rounded corners are doing something slightly odd in IE but it's fine... The biggest problem now is that I don't have a bottom margin on the main div but I can live with that if I can't figure it out.