I have a question that I haven't found addressed in the various CSS layout models I've looked at, so I thought I'd post it here.
I'm working on a site that uses a basic fluid/fixed two-column layout. The content of the site is in the left div, and the sidebar in the right. The sidebar has a fixed width of 200 pixels or so, and the content expands to fill out the remaining width of the parent.
Here's what the code looks like:
<div style="width: 90%; margin: 10px auto 10px auto;"> <!-- site container -->
<div style="margin-right: 200px;">Content goes here.</div>
<div style="float: right; width: 200px;">Menus goes here.</div>
<div style="clear: both;"></div> <!-- float-clearer div -->
</div>
This is a pretty standard approach and works fine for the most part, but the issue is that the design of the site requires the sidebar to only appear in certain cases. All of the HTML is generated through PHP, and the "get-content()" function doesn't know whether the "get-sidebar()" one will be called or not.
When the sidebar is called, I'd like the content to expand out to fill the parent div while leaving enough room for the sidebar. If there is no sidebar, the content should expand out to fill the entire width of the parent.
Is there any way to do this with CSS -- perhaps using "auto" for the content margins -- without relying on PHP/JavaScript?
You might consider doing it like this:
<div style="width: 90%; margin: 10px auto 10px auto;"> <!-- site container -->
<div style="background-color:#CCC;height:100%;">
<div style="background-color:#444;float: right; width: 200px;height:100%;">Menus goes here.</div>
Content goes here.
</div>
<div style="clear: both;"></div> <!-- float-clearer div -->
</div>
By doing it that way, the menu sits inside the main div and there is no margin-right, so when the menu goes away, the text expands to fill the space.
The "height:100%;" ensures that the menu and content boxes stretch to the same height. You could also set this to a pixel or em amount or a percentage less than 100 if you want.
Instead of floating the sidebar, try this:
#sidebar {
display: inline-block;
display: -moz-inline-box;
-moz-box-orient: vertical;
vertical-align: top;
zoom: 1;
*display: inline;
}
Would it be possible to add a class to the body using PHP? Something like "one-col" or "two-col" depending on the context. Then you can give the content div a margin when there is a sidebar, but not when there isn't.
Related
I have a fixed size wrapper consisting of:
Header that is sized to the whats inside
Footer that is fixed size
Content container that should use the remaining space of the wrapper
The problem occurs with images. I would like for images to resize to fit the content container both in height and width. Right now images overflow the wrapper in height.
Here is the code. The wide image is acting correct, resizing to fit, but the long giraf is not.
In the following fiddle overflow is set to scroll to debug. The endgoal is no overflow.
https://jsfiddle.net/sghp68r0/
A not so flexible solution would simply be to give the imageFit class a height like
img {
max-width: 100%;
max-height: 100%;
}
.imageFit {
object-fit: contain;
height: 150px;
}
But this I would rather avoid hardcoding the height.
My goal is that it looks like this (no overflow):
if i am right you want this. Please do let me know.
Drag the height in fiddle you see the images are adjusting with heigh.
Here is my fiddle link:-
https://jsfiddle.net/exa3y7w9/
<div class="wrapper">
<div class="header">
Sized to content <br />
Sized to content <br />
</div>
<div class="content">
<div class="imageWrapper">
<img src="https://cdn.pixabay.com/photo/2017/10/10/22/24/wide-format-2839089_960_720.jpg">
</div>
<div> 2 images and some text that fills remaining space </div>
<div class="imageWrapper">
<img src="http://clipart-library.com/data_images/258951.jpg">
</div>
</div>
<div class="footer">
There is some text in fixed size container
</div>
</div>
So apparently you can fix overflow in flexbox by setting height of the containing div to 0 (for safari it should be min-height: 0). Have a look at this example. If you remove height breaks.
https://jsfiddle.net/oz20qgw9/
.content {
background-color: green;
flex:2;
height: 0; //THIS IS THE KEY!
}
The main issue that is not treated in similar questions listed below is a FORM object that has a variable part and a non variable footer (submit buttons)
The aim is to display:
A header (a table (width:100%) with a logo and a text in second cell): size should be the smallest possible with all content displayed
A FORM (containing 2 parts):
Fields are in a div that will expand to all space remaining and will scroll if it lack space. (minimum size: 1 text line)
Submit / Rest buttons are in a table and should ALWAYS be visible and not resized in anyway. At worst the stick to bottom of browser window.(except if browser window becomes ridiculously small of course)
Nothing should go below bottom of browser window (except if user resize to a ridiculous size).
Hardcoded height is NOT an option (except the 100% for technical reasons - body or column parent for example). Header and footer height MUST be autocomputed by browser to use minimum space while displaying all content. If user reduce the width of the browser window increasing the header or footer text to wrap on more lines, the height must grow accordingly. Thus percentage or viewport heigh is not an option as it is arbitrary and can't take car of the user zoom, the browser width resize and such.
I've tried the following layout:
<div id="column">
<div id="header>
<table><tbody>
<tr><td>LOGO</td><td>Some intro text on a few lines</td></tr>
</tbody></table>
<!-- optionnel error line (arbitrary length) if previous form submission failed -->
</div>
<form>
<div id="variable_scrollable_content">
<!-- multiple field sets hosting some input (text, select, ...) -->
</div>
<div id="footer">
<table><tbody>
<tr><td>Save button</td><td>Reset button</td></tr>
</tbody></table>
<!-- A few lines of text -->
</div>
</form>
</div>
After I gave a careful view to similar questions (see below), I was unable to find something that could handle the FORM object that has a variable size scrollable part and a fixed footer.
I also gave a careful look at https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox with no more success.
I tried the flex approach for classes header, variable_scrollable_content and footer with no success. I also tried to put the form object in flex class but that doesn't work.
As I can't separate the FORM submit/reset buttons from the fields they manage, I don't know how to solve this.
header should stick to top of browser windows
footer (containing form control buttons) should stick to bottom of browser window at worst or stick at the end of the last fields if browser windows is big enough.
fields should be in a variable size container that uses all the remaining space between header and footer and has overflow-y:scroll; so it can scroll if it can't display its whole content.
In case the above simplified code is not sufficient, the "real" code can be found here:
https://github.com/finley/SystemImager/blob/initrd-from-imageserver-and-dont-package-initrd/webgui/edit_config.php
The full css is here:
https://github.com/finley/SystemImager/blob/initrd-from-imageserver-and-dont-package-initrd/webgui/css/screen.css
Similar questions
I have checked the following similar questions, and I believe my question is different as the main problem is the FORM object interfering with the layout:
scrolling content between fixed header & footer with variable height
Content height expand between fixed header and fixed footer
Make a div fill the height of the remaining screen space
Original question was here: variable height div between header and footer
I've just found the solution.
In this situation, the problem was the FORM object that would interfere with flex column children not at the same Dom level tree.
The simple solution was to move the FORM object so it includes the flex column it its whole content.
The above code becomes:
<form>
<div id="column">
<div id="header>
<table><tbody>
<tr><td>LOGO</td><td>Some intro text on a few lines</td></tr>
</tbody></table>
<!-- optionnal error line (arbitrary length) if previous form submission failed -->
</div>
<div id="variable_scrollable_content">
<!-- multiple field sets hosting some input (text, select, ...) -->
</div>
<div id="footer">
<table><tbody>
<tr><td>Save button</td><td>Reset button</td></tr>
</tbody></table>
<!-- A few lines of text -->
</div>
</div>
</form>
But this was not sufficient because setting flex column height to 100% (when body is also set to 100%) won't work. maybe the form object doesn't propagate the height?
The solution was to set height of column with vh (viewport height) unit.
So I set it to 100vh. Unfortunately, there are some glitches due to some border size and padding from parent objects and itself. So as a fallback I put it to 96vh, but this is ugly and I'll investigate and will remove the parasite border size padding that makes the body bigger than 100vh.
<body style="height: 100%">
<form>
<div style="display: flex; flex-flow: column; height: 100vh;">
<div id="header" style="flex: 0 0 auto;">foo bar</div>
<div id="content" style="flex: 1 1 auto; overflow-y: scroll;">Input fields</div>
<div id="footer" style="flex: 0 0 auto;">Control buttons</div>
</div>
</form>
</body>
The above sump is bigger than 100vh in height.
There are 2 solution to fix that:
Remove any border padding or such from parent object.
Set the column to an absolute position (0,0)
Alternative solution to scrollable FORM in flex content with fixed footer containing control buttons is to move FORM control buttons outside the form.
The code then looks like:
<body style="height: 100%">
<div style="display: flex; flex-flow: column; height: 100%;">
<div id="header" style="flex: 0 0 auto;">foo bar</div>
<div id="content" style="flex: 1 1 auto; overflow-y: scroll;">
<form id="foobar">
Input fields
</form>
</div>
<div id="footer" style="flex: 0 0 auto;">
<button form="foobar" type="submit" formmethod="POST">Submit</button>
<button form="foobar" type="reset">Reset</button>
</div>
</div>
</body>
The advantage is that it works with height 100% as it takes account of margin borders and padding of parent (while vh is an absolute viewport size).
I have a page which looks like this:
Content contains a static table of fixed width (determined by content) inside a centered div. Below content there is a div that contains a line of text and an image below that text. It is meant to float on the left of the Content. The page and image has max-width and max-height. But when page is resized, Image shrinks twice slower than the page. This causes the page to look like this:
I want Image to always be filling the most of that white gap on the left. When the page is resized, the Image should also resize accordingly.
http://jsfiddle.net/FZ4KG/
Html:
<section align="center">
<h4 align="center">Heading</h4>
<div align="center">
<table>Content</table>
<div id="image_box">
<p align="left">Text above image</p>
<img src="img.png" id="image">
</div>
</div>
</section>
Css:
#image_box {
padding-left: 15px;
height: 0px;
top: -75px;
position: relative;
}
#image {
float: left;
max-width: 20%;
}
A few things before I'm able to fully comprehend what it is you're looking for.
It's strange how you're using the HTML5 <section> tag with a deprecated, and as of HTML5 removed, align attribute. And still strange the use of an inline style when using css on those elements.
I will assume you're looking to center those elements within their parent containers. To achieve this, you would need to use a set width and set the horizontal margin of the element to auto.
div {
margin: 0 auto;
}
You also have a typo in your mark up. The DIV id says imabe_box. Assume it's supposed to be image_box.
<div align="center">
<table>Content</table>
<div id="imabe_box"> // ID should be set to 'image_box'
<p align="left">Text above image</p>
<img src="img.png" id="image">
</div>
</div>
Please add more code or reply to the answer and we can help you further.
Basically what I have is an HTML page with a "main content" block, if you will. All main content for that page goes in the div I have for it. What I want is to have a column with more stuff to the right of it, but whatever I try to do it always ends up going either below it or in some random place. Here is the code for my page, if anyone could help guide me through it that would be awesome.
HTML: http://pastebin.com/Hh2TNGdj
CSS: http://pastebin.com/ZCEJkFmH
Thanks.
You were probably close... putting in your new div straight after #pagecontent, and floating it right, then floating the #pagecontent div left, will allow them to sit side by side.
Note that the next content (footer, for instance) will need to be cleared properly so it won't overlap your floated divs.
I would switch to using HTML5 tags, personally. If I were to do something like this, I would go with code along this line (untested):
<div id="wrapper"> #wrap both sections in a container
<section id="left">Left Section</section>
<section id="right">Right Section</section>
</div>
For the CSS, you can do something like this:
#wrapper {
width: 1000px;
height: auto;
}
#left {
width: 500px;
height: auto;
float: left;
}
#right {
width: 500px;
height: auto;
float: left;
}
Some important things to remember. If you add padding, subtract that from the width (if padding is on both left and right, subtract padding x2). On your footer, put clear: both.
Hope this helps you out.
Here's a fiddle: http://jsfiddle.net/n6D7U/
new div #aside,
both columns are floating with fixed width (700+20+240 pixels here),
last CSS rule is there because parent has only floating children and thus no more content in the flow to push down the background...
I think this should work:
<div style="padding:20px;">
<div id="pagecontent">
<span class="main-content-font">
The title of this page goes in the gray box above. This is the homepage, you can put <u>anything</u> here (the main content of your website
which has some neat features and explains what your site is about should go here)!<br />
<br>
Content, content, and more content!<br />
<br>
Try to make it fill up as much space as possible, making the page longer. Don't fill it with useless junk, just anything
you can think of that will benefit the page.
</span>
<span class="whatever">
some things
</span>
</div>
</div>
I haven't tried it, but making main-content-font a span will not add a newline, so the whatever span will be placed to its right.
I'm helpless, tried my best understanding CSS but it's just not for me.
I would like to make a really simple MasterPage:
at the top a div of full width and height 40px (1)
at the bottom also a div of full width and height 40px (2)
in the middle:
on the left: a div of width 200 px (3)
on the right side of the left div: a div with contentPlaceHolder (4)
What I would like to get is: if i make some site that uses my master page and place a panel in the contentPlaceHolder that has width 800px, I would like my site to adjust to it - top, middle and bottom divs to have their width of 1000px (200 + 800). I also wouldn't like (and I have a huge problem with that) the (4) to move down if I resize (shrink) the browser window - I would like all the divs to be blocked.
This is my master page html:
<div>
<div class="header">
</div>
<div>
<div class="links">
</div>
<div class="content">
</div>
</div>
<div class="footer">
</div>
</div>
What kind of CSS do I have to write to make this finally work?
Not sure if you have checked into this or not, but we use the YUI-Grids CSS Framework for our layouts. It keeps us from having to spend a lot of time on CSS, which we are not great at being developers.
There is even a grid builder which will let you graphically layout a page, and then copy and paste the required HTML to make it happen :)
To prevent floated divs from being "squeezed" out of the alignment you want, you usually use either width or min-width.
For example, in this code the div containing the links and content will never be smaller than 1000 pixels. If the screen is smaller than 1000 pixels, a scrollbar is displayed.
<div style="min-width: 1000px">
<div class="links"></div>
<div class="content"></div>
</div>
You could also use width instead of min-width:
<div style="width: 1000px">
<div class="links"></div>
<div class="content"></div>
</div>
The difference between the two is simple: if you specify min-width, the div CAN grow to be larger if it needs to. If you specify width, the div will be exactly the size you specified.
Be aware that min-width is not supported by IE6.
Here's a quick stab at specific CSS/Markup for this problem.
Markup:
<!-- Header, etc. -->
<div class="contentView">
<div class="links">
</div>
<div class="content">
</div>
</div>
<!-- Footer, etc. -->
CSS:
.contentView {
/* Causes absolutely positioned children to be positioned relative to this object */
position: relative;
}
.links {
position: absolute;
top: 0;
left: 0;
width: 200px;
}
.content {
padding-left: 200px;
}
You might want your footer to be "sticky." Check here for information on that: http://ryanfait.com/resources/footer-stick-to-bottom-of-page/
How appropriate this is depends on precisely what the design calls for. This makes the links section more of a floating box on the left than a column for example.
This ends up looking like this (.content is green, .links is red):