A html section (content + top margin) should take up whole viewport.
There is no other margins except top. Section is not going to have much content in it
This could be achieved by setting something like
height:60vh
margin-top:40vh
But the problem is, section height may change due to viewport width change or content amount
So i need some solution for margin to be calculated automatically. Something like margin-top: 100vh-height.
Context
there is bunch of sections directly in body that are located vertically, some of them should be like i described ( a horizontal line that takes 1/3 - 2/3 of vp height, some of them take 100vh and don't have a vertical margins.
body have a
display:flex;
flex-direction:column;
on it
Notes
I know that it is possible to do by
1) Wrapping everything in unnecessary level of divs
2) Using js
But I want to avoid those solutions and keep html as minimalistic as possible. So I need a way to calculate margin or other changes to css to achieve this (suggestions about changing approach to layout in general (but only css) are welcome)
clarifying image
body { display:flex; flex-direction:column;}
body > section { min-height:vh; margin:0; background-color: #e13652;}
.sectionHorizontal { min-height:10em; margin-top:60vh; }
<section class="sectionHorizontal">
<p> horizontal section with some content, it should take part of a viewport and the rest should be filled by margin </p>
</section>
<section>
<p> another section. but this one takes 100% of viewport</p>
</section>
<section class="sectionHorizontal">
<p> another horizontal section, that have more content and is higher than the first one</p>
</section>
More notes
I'm asking not how to make a section 100vh but how to make section + empty space before it =100vh. Or how to move stuff inside it
I wanted to keep example as simple as possible, but actually section has background and itself may contain not only one but several different elements that have their own positioning
I'm still not sure if I understand your problem correctly or not, but have a look at the following. If you can clarify further, that'd be helpful.
section {
border-bottom: 1px solid #ddd;
border-top: 1px solid #ddd;
display: flex;
flex-direction: column;
height: 100vh;
}
section.horizontal {
justify-content: flex-end;
}
<section class="horizontal">
<p> horizontal section with some content, it should take part of a viewport and the rest should be filled by margin </p>
</section>
<section>
<p> another section. but this one takes 100% of viewport</p>
</section>
<section class="horizontal">
<p> another horizontal section, that have more content and is higher than the first one</p>
</section>
Assuming your example code this would be the only way possible without changing the html.
* {
margin: 0;
padding: 0;
}
body {
display:flex;
flex-direction:column;
}
section {
margin-top: 100vh;
height: 0;
}
section p {
background: #ccc;
transform: translateY(-100%);
}
section:not(.sectionHorizontal) p {
height: 100vh;
}
<section class="sectionHorizontal">
<p> horizontal section with some content, it should take part of a viewport and the rest should be filled by margin </p>
</section>
<section>
<p> another section. but this one takes 100% of viewport</p>
</section>
<section class="sectionHorizontal">
<p> another horizontal section, that have more content and is higher than the first one</p>
</section>
Related
Here's an example that goes halfway there:
http://jsfiddle.net/gt9vz4qk/1/
CSS: #content {background-color: #fdd; overflow: auto; height: 70vh;}
HTML:
<button>Hello</button>
<div id="content">
A<br>A<br>A<br>A<br>A<br>A<br>A<br>A<br>A<br>A<br>
A<br>A<br>A<br>A<br>A<br>A<br>A<br>A<br>A<br>A<br>
A<br>A<br>A<br>A<br>A<br>A<br>A<br>A<br>A<br>A<br>
</div>
<input>
Using relative size units like vh helps, but I feel like I'm missing something really basic. As you can see, if you resize the window or even the splitter on the jsfiddle website far down, the other elements start compressing and a second scrollbar pops up. The only scrollbar should be the overflow one.
Another way to think about this is that I want the top elements to take up as much space as they need, the bottom elements to take as much space as they need, and anything else should be taken up by the central element.
Here's a flexbox solution:
html, body {
height: 100%;
margin: 0;
}
body {
display: flex;
flex-direction: column;
}
#content {
background-color: #fdd;
overflow: auto;
flex: 1;
}
<div>
<button>Hello</button>
</div>
<div id="content">
A<br>
A<br>A<br>A<br>A<br>A<br>A<br>A<br>A<br>A<br>A<br>A<br>A<br>A<br>A<br>A<br>A<br>A<br>A<br>A<br>A<br>A<br>A<br>A<br>A<br>A<br>A<br>A<br>A<br>A<br>
</div>
<div>
<input>
</div>
Fiddle
this is what I'm trying to achieve.
I already know positioning, centering and stuff. The problem I have here, and which I want to ask you guys, is: what's the best practise to have a centered div and everything inside it to be centered while having a single one's background color exceed to the full width of the page always keeping it centered?
It's a super common layout in fact, I just don't know what's the correct way of "thinking" it.
Should I think the layout as "I make a big box with 1280px width, center it with margin: 0 auto; and then do something special for that div's background - and only the background, content should stay in place - to exceed or should I make something like a class to center every single element the same way but repeating my code?
So basically, should be all inside a single box and that div exceed in the background only or it's actually better to center everything separately by repeating the code?
Keep in mind the site is not responsive and doesn't need to adapt/scale and also that the light grey area is also the "body" colore so the dark grey area is the only special case in the page that should exceed.
My suggestion:
I would create three basic containers for the full width support. Then nest content in it!
html, body{
padding: 0;
margin: 0;
border: 0; /*ie older versions*/
}
header {
background-color: antiquewhite;
}
section{
background-color: ActiveCaption;
}
footer{
background-color: aquamarine;
}
.inner-wrapper{
max-width: 300px;
margin: 0 auto;
border-left: 1px solid black;
border-right: 1px solid black;
height: 80px;
text-align: center;
}
section .inner-wrapper{
height: 200px;
}
<header>
<div class="inner-wrapper">
<div>some content</div>
</div>
</header>
<section>
<div class="inner-wrapper">
<div>some content</div>
</div>
</section>
<footer>
<div class="inner-wrapper">
<div>some content</div>
</div>
</footer>
This is a absolut basic but robust layout an i used it several times. It is very easy to make it responsive with media queries or fluid with percentage settings!
In my opinion you should give to the body or to a container div the background color property and that div to be full width and height then the div that is in the middle you should give a margin:0 auto; and a specific width, this is what I would do, but it depends on what you are trying to do, what is the most common way you do it in order to you to know to how to do it the same next time, faster.
Can anyone help me with position my content block?
It looks good if there are a lot of content, but not when window higher than content block.
Actualy I need that "content" block on my picture teked all free space (height) and thats why footer stick to the bottom.
I have next HTML markup:
<div>
<header></header>
<nav class="breadcrumbing"></nav>
<section class="left_nav"></section>
<section class="content"></section>
<footer></footer>
</div>
With this CSS:
html,body{width:100%;margin:0;padding:0;}
body{background-color:#629302}
body>div{width:400px;height:100%;margin:0 auto;background-color:#FFF;}
body>div>header{height:50px;background-color:#9dc155}
body>div>nav.breadcrumbing{display:block;height:10px;margin:0;padding:0;}
body>div>section.left_nav{width:172px;margin:8px 20px;float:left;background-color:#cdef88}
body>div>section.content{width:168px;float:left;}
body>div>footer{padding:19px 19px 22px;background-color: #e58b04;clear:left;}
I allready tried answers from Is it possible to get a div's height to be 100% of an available area? and some same questions but with no luck.
ALso my live HTML has backgroun-images, so I can't just put footer to the bottom with position:absolute.
There I post my HTML to preview: jsfiddle.
UPD: scaled live preview:
You will have to set the html and body height property to 100%; then you can set the footer height to 100%; this will tell the main container elements the real meaning of 100% and it will work.
Your updated fiddle
Basically, these are the rules you have to add:
html, body {
height: 100%;
}
footer {
height: 100%;
}
Update
Ok, I might have misunderstood your requirements, here is a cleaner example:
Working example
Basically, what you additionally do in this example is having your wrapper element display:table with an height: 100%, then you make your footer display as table-row.
Important note: This solution uses display-table which is compatible only for IE8+. If supporting IE7 is an issue for you, then you have two solutions that I can think of out of my head:
Either you use a fixed-width footer, push it below the content and then pull it back with a combination of negative margin and padding.
Or you fallback to support of older browser by putting your footer in position using some javascript.
This the breakdown of the code:
HTML
<div class="wrapper">
<header></header>
<section class="main-content">
{child elements of your main-content area}
</section>
<footer></footer>
</div>
CSS
html, body {
height: 100%;
margin: 0;
}
.wrapper {
display: table;
margin: 0 auto;
height: 100%;
}
.main-content {
display: table-row;
height: 100%;
}
footer {
display: table-row;
}
Here's an updated fiddle
The crux of this is setting the body to be absolutely positioned to the viewport. From there, if you wanted to allow it to scroll as you normally would, then you would change the footer's position to fixed and the content div's CSS to this:
body>div>div{width:400px;height:100%;margin:0 auto;background-color:#FFF;
position:absolute; top: 0; bottom: 0; overflow-y:auto;}
I've wrapped your content div in another to allow for the automatic margins to center your page, and then defined the footer's box sizing as border-box to account for the padding you're adding to it as well.
Please, consider the following jsFiddle - http://jsfiddle.net/mark69_fnd/hwCuB/ (you can find the code after the body of the question).
It represents a trivial example of the classic header, content, footer HTML layout. Notice that:
The content never overlaps with the footer. Resizing the window will finally create a vertical scrollbar rather than move the content over the footer.
There are no redundant scrollbars.
No absolute heights, except of the footer, which may be assumed to be no higher than 2em.
The content height is less than the available height between the header and the footer.
I would like to keep the first three properties, but change the last one, so that the content height is the full height between the header and the footer. And I would like to do so without resorting to javascript.
How can I do so, if at all?
EDIT
The given html and css are just an example. You are free to change them as long as the final result satisfies the conditions of my question.
EDIT2
Apparently, I am not very clear on what I want to achieve with the content. Here is what I have now:
Notice how the content does not extend the full height available to it between the header and the footer.
What I am after is this:
(edited in mspaint, I do not know to do it really)
EDIT3
Added an except clause to the 3rd condition:
except of the footer, which may be assumed to be no higher than 2em.
HTML:
<html>
<head>
<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/3.7.3/build/cssreset/reset-min.css">
</head>
<body>
<div class="container">
<div class="header">
Header goes here.
</div>
<div class="content">
<div class="innerWrapper">
Content goes here.
</div>
</div>
<div class="footer">
<div class="status">
Footer goes here.
<div>
</div>
</div>
</body>
</html>
CSS:
html, body {
height: 100%;
width: 100%;
}
.container {
position: relative; /* needed for footer positioning*/
margin: 0 auto;
height: auto;
min-height: 100%;
background-color: #ddd;
}
.content {
padding: 0em 0em 2em; /* bottom padding for footer */
background-color: #bbb;
}
.footer {
position: absolute;
width: 100%;
bottom: 0; /* stick to bottom */
}
.status, .header {
background-color: #999;
border: solid 1px #000000;
}
There might be couple ways to do this, but the only ways i can think of at the moment all involve setting/knowing the height of your header and footer.
Here is one using display:table http://jsfiddle.net/fLnkf/
There may be other solutions depending on if your requirements allow you to change your html or use CSS3.
hope this helps!
I've successfully used the beautiful Susy grid system to create a responsive layout similiar to the one of WebDesignerWall.com:
What i failed to implement is a position:fixed sidebar.
Such a sidebar would not scroll when the page is scrolled and stays on the same place. That's fantastically convenient (anyway, you actually can't put more content into the sidebar, because it would clutter the top of page in a narrow window).
My layout goes crazy whenever i apply position:fixed to a column:
The colored blocks are declared three-column wide, but stretch further when position:fixed is applied to the sidebar..
I think the problem is that the width of the sidebar is relative, i. e. set in percentage. Due to position:fixed, the width is measured against the width of the browser window, not its container (though i set the container to position:relative).
The question is: how do i make a column fixed to the window while measuring its width against its container, not the viewport?
Maybe it's possible to fix the position of an element with JS?
PS I've tried the width: inherit solution, but it wasn't of any help to my situation.
The way to do it is with a second container. I don't know your exact code, but here's an example. Let's assume your structure is something like this:
<div class="page">
<header class="banner">
<h1>header</h1>
</header>
<nav class="navigation">
<ul class="nav-inner">
<li>navigation link</li>
</ul>
</nav>
<article class="main">
<h2>main content</h2>
</article>
<footer class="contentinfo">
<p>footer</p>
</footer>
</div>
The only important assumption I made there was ensuring an extra wrapper around my navigation sidebar. I have both the <nav> tag and the <ul> tag to work with. You can use any tags you want, as long as the sidebar has two that can be used for structure - the outer for a fixed container, and the inner for the sidebar itself. The CSS looks like this:
// one container for everything in the standard document flow.
.page {
#include container;
#include susy-grid-background;
}
// a position-fixed container for the sidebar.
.navigation {
#include container;
#include susy-grid-background;
position: fixed;
left: 0;
right: 0;
// the sidebar itself only spans 3 columns.
.nav-inner { #include span-columns(3); }
}
// the main content just needs to leave that space open.
.main { #include pre(3); }
// styles to help you see what is happening.
header, article, .nav-inner, footer {
padding: 6em 0;
outline: 1px solid red;
}
Cheers.
You can't, fixed-position elements are detached from their containers, position: relative or no position: relative. Just set its width to an absolute value - it looks like your content is always 760 pixels wide, right?
Maybe it's possible to fix the position of an element with JS?
Yes, but it will be tedious and isn't the ideal solution .
Instead, calculate the appropriate width using JavaScript and assign it, instead of using the percentage directly in CSS. Here's a basic outline:
function updateSize() {
var outer = document.getElementById("outercontainer"); //get the container that contains your sidebar
var navcol = document.getElementById("navcol"); //get the sidebar (which is supposed to have position: fixed;)
navcol.style.width = Math.floor(outer.offsetWidth * 45/100) + "px"; //or whatever your percentage is
}
updateSize();
window.onresize = updateSize; /*make sure to update width when the window is resized*/
Note: the IDs used above are just placeholders -- you will need to modify them to fit your actual page.
Why don't you just use math? =)
Example html:
<div class="container">
<div class="col">
<div class="fixed">This is fixed</div>
</div>
</div>
CSS
.container {
width: 80%;
margin: 0 auto;
}
.col {
float: left;
width: 33.3333333333%;
}
.fixed {
position: fixed;
width: 26.666666666%; /* .container width x .col width*/
}
position:fixed works like position:absolute so it isn't positioned in relation of its container. It simply floats into your document.
A quick fix would be something like this:
<div id="fixed-element" style="width:30%"> /* 30% of the document width*/
lorem ipsum dolor sit amet
</div>
<div id="faux-sidebar" style="width:30%; display:block"> /* 30% of the document, leave it empty, so it acts like a placeholder for the fixed element*/
</div>
<div id="the-rest" style="width:70%"> /* the rest of the website goes here */
more lorem ipsum than ever before
</div>