I have 2 container: I want to put the first on top and center it (no problem to do this with margin:0 auto;).
However, I'm not able to put the second in the bottom center.
I'm trying to align a div to the center in bottom position (like a footer div but not at width 100%).
My div has a width of 90% and it is impossible to center it. It is always aligned to the left.
If I use margin: 0 auto; it goes to the center but not at the bottom of the page. If I use position: absolute; bottom:0; it goes in bottom of the page but not aligned to the center.
Does anyone have an explanation?
PS: I would like to keep the HTML unchanged and not create another div to contain the second div.
.a {
width: 90%;
height: 10%;
background-color: beige;
margin: 0 auto;
}
.b {
position: fixed;
width: 90%;
height: 10%;
margin: 0 auto;
bottom: 0;
background-color: aliceblue;
}
<div class="a">A</div>
<div class="b">B</div>
I don't have high enough reputation to comment on answers, but you can use
left: 0; right: 0;
on your .b div without having to put a container around it. I've tried it out and is working under Google Chrome.
There's some more explanation here - CSS Fixed position with Auto Margin
So with position: fixed you've effectively detached that element from the DOM flow so margin: 0 auto is now irrelevant, instead you'll want to do one of several other options to accomplish your goal. A couple examples (Note: the snippet editor won't do position: fixed well either so you'll want to try it locally);
.a {
width: 90%;
height: 10%;
background-color: beige;
margin: 0 auto;
}
.b {
position: fixed;
bottom: 0;
left: 5%;
right: 5%;
height: 10%;
background-color: aliceblue;
}
<div class="a">A</div>
<div class="b">B</div>
OR,
.a {
width: 90%;
height: 10%;
background-color: beige;
margin: 0 auto;
}
.b-container {
position: fixed;
bottom: 0;
left: 0;
right: 0;
}
.b {
margin: 0 auto;
width: 90%;
height: 10%;
background-color: aliceblue;
}
<div class="a">A</div>
<div class="b-container">
<div class="b">B</div>
</div>
Hope this helps, cheers.
I'm not sure what other HTML you have in place besides the two divs. Will you have a div in-between "a" and "b"? Will there be a wrapper div around all the divs? You could use CSS grid for your solution.
Here's the CSS:
/* ideally this would be on a wrapper div instead of the body tag */
body {
display: grid;
grid-template-rows: 90px 1fr 90px; /*This is the row heights*/
grid-template-columns: 1fr;
height: 100vh;
width:90%;
margin:0 auto;
}
.a {
grid-row: 1 / 2;
background-color: beige;
}
.b {
grid-row: 3 / 4;
background-color: aliceblue;
}
Then your markup would stay the same:
<div class="a">A</div>
<div class="b">B</div>
Give .b the following:
left: 5%;
margin: auto won't work on absolutely-positioned elements, only static ones.
Do you want a header and a footer? And the footer always on bottom?
Use a more modern flex layout to do this.
https://stackblitz.com/edit/html-header-main-footer?embed=1&file=style.css
<body>
<header>Header</header>
<main>Main</main>
<footer>Footer</footer>
</body>
html, body {
width: 100%;
height: 100%;
margin: 0;
}
body {
display: flex;
align-items: center;
flex-direction: column;
}
header, main, footer {
width: 100%;
max-width: 600px;
text-align: center;
}
main {
flex: 1;
}
Q: How does it work?
A: The main is a flex spacer.
PS: header, main and footer is just a suggestion. You also can use just divs.
#chris..... solution A not work and B I want to keep unchange html #utkanos.....left: 5% is good but i don't want to calculate the space beetween (image if the width was 775 px) #Dominik.... div are not fully width and the 2 container could be different width
Related
I want to create a layout, where there are 3 divs in the "background", and one div in front but it does not cover all the screen, it is just like a "pop-up" (but it is always there).
This is what I want to achieve:
The white div is the one that should be in front. The green div at the top will have buttons, so the background divs are not just pictures, and later I want my website to be responsive.
What is the idea behind making these kinds of layout? Can you suggest some techniques? How would you do it? (I would appriciate basic codes, but advice is always welcome.)
I did something like this, hope it helps.
* {
margin: 0;
padding: 0;
height: 100%;
}
div {
background: white;
}
.DivRow {
display: flex;
flex-direction: column;
width: 40%;
}
#row1 {
background: #23B14D;
}
#row2 {
background: #00A3E8;
}
#row3 {
background: #B5E41A;
}
.DivColumn {
margin: 20px;
background: white;
position: absolute;
width: 34%;
height: 90%;
top: 0;
}
<div>
<div class="DivRow">
<div id="row1"></div>
<div id="row2"></div>
<div id="row3"></div>
</div>
<div class="DivColumn"></div>
</div>
Try something like this. Use 4 div blocks and give them al a color. The last one is the white one and you give it an absolute position. Add margin and height to all the div and you create your image.
The example:
.top,
.middle,
.bottom {
height: calc(100vh / 3); /* Fill the viewport width 3 boxes */
}
.top {
background: #008000; /* Green background color */
}
.middle {
background: #0000FF; /* Blue background color */
}
.bottom {
background: #00FF00; /* Lime background color */
}
.center {
position: absolute; /* places this div on top */
top: 0; /* Position the div on the top */
right: 0; /* Position the div on the right */
bottom: 0; /* Position the div on the bottom */
left: 0; /* Position the div on the left */
background: #FFF; /* White background color */
margin: 80px; /* Makes sure you can see the other dives */
height: calc(100vh - 160px); /* Add the viewport height minus the top and bottom marin */
}
<div class="top"></div>
<div class="middle"></div>
<div class="bottom"></div>
<div class="center"></div>
Try adding media queries to the margin or max-width to make it responsive. If you want to put all the content in the whitebox and make it scroll, add overflow-y: auto.
The simplest way to organize sections with responsiveness without the need to use media queries is using the CSS grid. It is an amazing tool and you use much less code to this. I recommend you to read this: https://css-tricks.com/snippets/css/complete-guide-grid/ and get familiar with the CSS grid. it will solve more than your problems. You can see below how I solved your problem with much less code than usual. I hope this answers your question. don't forget to put a flag if you liked my solution! have a nice day of code :)
.container{
width:100%;
height:100vh;
display:grid;
grid-template-columns: 1fr 80% 1fr;
grid-template-rows: 1fr 1fr 4fr 1fr 1fr;
}
.div1{
background-color:#27ae60;
grid-column: 1 / -1;
grid-row:1 / 3;
}
.div2{
background-color:#0c2461;
grid-column:1 / -1;
grid-row: 3 / 4;
}
.div3{
background-color:#b8e994;
grid-column: 1 / -1;
grid-row: 4 / 6;
}
.div4{
background-color:white;
grid-column: 2 / 3;
grid-row: 2 / 5;
}
<section class="container">
<div class="div1"></div>
<div class="div2"></div>
<div class="div3"></div>
<div class="div4"></div>
</section>
After a little bit of effort I came up with this
Lets dig into it a little bit
The html is pretty simple
<div id="app">
<div class="flex">
<div class="row" id="item1"></div>
<div class="row" id="item2"></div>
<div class="row" id="item3"></div>
</div>
<div id="top"></div>
</div>
we've got an upper level container #app, a container for our layers div.flex
and div.top, the element we'll be positioning atop.
The css starts off with some boilerplate, just to get things started
html,body{
margin:0;
padding: 0;
height: 100%;
}
.flex{
display: flex;
flex-direction: column;
}
#item1{
background: teal;
}
#item2{
background: pink;
}
#item3{
background:orange;
}
the html, body bit is just to make the demo look good in jsfiddle. Otherwise it would be offset. Gross.
We then define .flex so that each of it's elements fill the container i.e. flexes across all columns left to right
finally we give each element .row a color
With this we end up with 3 band of color of equal size all evenly spaced within the div
The interesting part
#app{
position: relative;
}
#top{
position: absolute;
top: 0;
background: white;
margin: 20px;
width: calc(100% - 40px);
height: calc(100% - 40px);
}
Now here I have to admit that my understanding is a bit shaky, if I'm wrong please correct me.
What we want now is for #top to break the normal flow of the layout. We don't want it to simply be placed below the previous div. To do that we can say position: absolute, however that on it's own is not enough.
position: absolute looks for the nearest ancestor with position: relative and aligns itself with that ancestor. So if we want to position #top relative to its container #app
#app{
position: relative;
}
#top{
position: absolute;
top: 0;
}
top:0 aligns #top to the top of #app. Play around with it in the fiddle to get a solid grasp.
Finally
#top{
position: absolute;
top: 0;
background: white;
margin: 20px;
}
we want a small margin around the edge of #top so we can see the colors behind, and we've got that covered with margin: 20px. Now we need to subtract 2 * margin from the width and height to line everything up correctly
#top{
position: absolute;
top: 0;
background: white;
margin: 20px;
width: calc(100% - 40px);
height: calc(100% - 40px);
}
Hope this helps!
Fin
P.S. Play with the numbers in the fiddle. That should help a lot
html,body{
margin:0;
padding: 0;
height: 100%;
}
div{
width: 100%;
height: 100%;
}
.flex{
display: flex;
flex-direction: column;
}
#item1{
background: teal;
}
#item2{
background: pink;
}
#item3{
background:orange;
}
#app{
position: relative;
}
#top{
position: absolute;
top: 0;
background: white;
margin: 20px;
width: calc(100% - 40px);
height: calc(100% - 40px);
}
<div id="app">
<div class="flex">
<div class="row" id="item1"></div>
<div class="row" id="item2"></div>
<div class="row" id="item3"></div>
</div>
<div id="top"></div>
</div>
In the code sample I did:
reset all margins/paddings to 0
set body height to 100%
set flex container height to 96%
set flex container margin-top to 2%
Now this gives me a scroll on the body even if the flex containers height + margin-top only sums up to 98%, so my question is, can't I use margin-top is this way and where does the extra space come from forcing the body to scroll?
Setting the body to overflow:hidden removes the scroll, but that feels more like a band-aid and not considered as a solution (unless this is a "behavior-by design" which needs that in this case).
Edit
Ways like remove the margin-top on the flex container and then set a padding-top: 2%; on the body or use position: relative; top: 2%; on the container or with absolute: position; I can make it work as expected though, but the case here is why margin-top: 2% doesn't do it.
* {
box-sizing: border-box;
padding: 0;
margin: 0
}
html, body {
background-color: gray;
height: 100%;
}
.outer {
display: flex;
flex-flow: column;
margin: 0 auto;
height: 96%;
width: 50%;
margin-top: 2%;
}
.top {
background-color: lightgray;
}
.middle {
background-color: darkgray;
}
.the-rest {
flex: 1 0 auto;
background-color: lightgray;
}
<div class="outer">
<div class="top">
top
</div>
<div class="middle">
middle
</div>
<div class="the-rest">
content
</div>
</div>
This is because percentage margins are based on the width of the containing block / element...in this case, the body.
W3C Spec
MDN
A <percentage> relative to the width of the containing block. Negative values are allowed.
I usually use vh and vw on html and body. In this demo I applied vh only since it looked like a vertically oriented demo. I also make the body and html position: relative. With vw and vh there's a real measured length that other elements (children of ::root) can actually set their relative measurements of 100%. I use position: relative because it makes the html, body sit rigidly inside the view port and the viewport units keep the body, html on the edge at 100vh and 100vw.
UPDATE
I think this behavior is due to collapsing-margins So if there's an illogical margin-top behavior, keep that in mind. There are several very specific circumstances that result in this odd behavior and there are a few solutions as well. The solution for these circumstances are as follows:
body, html { height: 100vh; } /* no relative or absolute positioning */
.outer { min-height: 100%; margin-top: -2%; } /* It's explained that the positive numbered margin-top is not effective and yet the negative value works but not like a normal negative value!? o_0
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
html,
body {
position: relative;
background-color: gray;
height: 100vh;
}
.outer {
display: flex;
flex-flow: column;
margin: 0 auto;
min-height: 100%;
width: 50%;
margin-top: - 2%;
border-top: 0;
}
.top- {
background-color: lightgray;
}
.middle {
background-color: darkgray;
}
.the-rest {
flex: 1 0 auto;
background-color: lightgray;
}
.marker {
position: absolute;
outline: 1px solid red;
}
<span class="marker" style="top: 0; left: 0;">top:0|left:0</span>
<span class="marker" style="top: 0; right: 0;">top:0|right:0</span>
<div class="outer">
<div class="top">
top
</div>
<div class="middle">
middle
</div>
<div class="the-rest">
content
</div>
</div>
<span class="marker" style="bottom: 0; left: 0;">bottom:0|left:0</span>
<span class="marker" style="bottom: 0; right: 0;">bottom:0|right:0</span>
My container is not touching my footer for the majority of cases and I'm not sure what's going on.
So here is my CSS code:
html {
min-height: 100%;
position: relative;
}
body {
margin: 0;
width: 100%;
height: 100%;
}
section {
height: 100%;
}
#container {
overflow: auto;
width: 80%;
margin: 0 auto;
background: red;
height: 100%;
}
.footer {
width: 100%;
position: absolute;
left: 0;
bottom: 0;
}
Here's my HTML:
<body>
<div id="container">
<section>
<p>Content goes here</p>
</section>
</div>
<div class="footer">Content</div>
</body>
So I have all of the heights set for parent elements,but there's still a big gap between the container and the footer. In cases where the content takes up the whole page, the footer and container ends up touching, but the content for some reason gets lost in the footer. How can I solve this issue?
Height based on percentage are tricky. vh is much better for such purposes.
Here is the solution: JSfiddle
#container {
overflow: hidden;
width: 80%;
margin: 0 auto;
background: red;
height: 100vh;
}
Make one adjustment to your CSS:
Add height: 100% to the html element.
html {
height: 100%; /* NEW */
min-height: 100%;
position: relative;
}
This will clear the way for all child elements to recognize their percentage heights, and the container will expand. Your min-height: 100% will still work because min-height overrides height.
DEMO: http://jsfiddle.net/au6tcodc/
(You'll notice a vertical scrollbar on the container in the demo. This is caused by the overflow: auto declaration in #container. If you want to remove the scrollbar switch to overflow: hidden (see all overflow values).
Examining this HTML:
<div class="wrapper">
<div class="content">
</div>
</div>
<div class="footer">
<hr />
<p>some text</p>
</div>
and CSS:
.footer {
position: absolute;
height: 100px;
width: 100%;
bottom: 0;
background-color: black;
}
.wrapper {
padding-bottom: 100px;
background-color: blue;
height: 100%;
}
.content {
width: 200px;
height: 100px;
margin: auto;
background-color: green;
}
html, body {
width: 100%;
height: 100%;
}
You can see that footer have position absolute and stay at the bottom of the page. wrapper will cover the remaining space and contain a content inside it. I want to vertical-align content without breaking the current layout. Do you have any suggestion?
Here is JSFiddle link. (Note: jsfiddle doesn't work as expected, there always a space beneath footer, this behavior doesn't occur when run the HTML file in browser).
Note: I don't want to use fixed height for wrapper, I want it covers all the remaining space, so please don't suggest me to use line-height
I tried the example here but it doesn't seem to work
NOTE I want the layout easy to modify (like add a header or content at the top) without breaking it therefore I want to avoid using absolute position on wrapper and content
NOTE 2 Sorry for not to clarify, actually, content doesn't have fixed size, its size depend on the content inside it, so the solution using negative margin doesn't work as I mentioned above
Here is one approach using the following CSS:
.footer {
position: absolute;
height: 100px;
width: 100%;
bottom: 0;
background-color: black;
}
.wrapper {
background-color: blue;
position: absolute;
top: 0;
bottom: 100px;
left: 0;
right: 0;
}
.content {
width: 200px;
height: 100px;
background-color: green;
position: absolute;
top: 50%;
left: 50%;
margin-top: -50px;
margin-left: -100px;
}
html, body {
width: 100%;
height: 100%;
margin: 0;
}
Use absolute positioning and then negative margins, since your content has well-defined
dimensions, this is relatively straightforward.
See demo at: http://jsfiddle.net/audetwebdesign/DgUV2/
For .wrapper, use the top, bottom, left and right offsets to stretch the div to the
full width and height, taking into account the 100px for the footer.
For .content, set top and left to 50%, the center point of the .wrapper and then adjust
for the center of the .content div using negative margins.
Remember to zero out the margin for the body or else you might see 10px whitespace
depending on your browser.
Add this to your .content
position: relative;
top: 50%;
transform: translateY(-50%);
Just 3 lines of code to vertical align
I was able to get it to work using Method 1 from the example you linked
I added the following:
.content {
width: 200px;
height: 100px;
margin: auto;
background-color: green;
/* THE BELOW WAS ADDED */
position: absolute;
top: 50%;
left: 50%;
margin: -100px 0 0 -100px;
}
html, body {
width: 100%;
height: 100%;
/* BELOW ADDED TO REMOVE EXTRA SPACE AROUND EDGES */
margin: 0;
}
jsFiddle of working example
Assume, that I have three boxes (divs) on website (see image below):
header with logo
content with some text
footer with contact info
Each box have unique color (in order: yellow, orange and blue) and black border.
I would like to website always fills the entire screen, the logo was on the top and the footer was at the bottom. So if there is not enough text in content, content should be extended, so that the footer was on the bottom. And if will be a lot of text in content, slider should appear on the right.
How do this in CSS? Important is that boxes have backgrounds. I found many solutions, but none doesn't work properly with backgrounds.
Solution Explained
The black box in your diagram gets min-height 100%, is the scrolling container, and is position relative, to allow child positions to be respective to it.
The red box in your diagram is actually composed of 2 boxes:
one for your dynamically-sized content; this has sufficient top and bottom padding to make room for your header and footer, and force the scrolling container to expand
one for the background; this is position absolute, with top and bottom position specified relative to the black box, its parent.
The yellow and blue boxes in your diagram can be position: absolute, top: 0 and bottom: 0, respectively... or however you choose to position them.
Here's a fiddle of it: http://jsfiddle.net/syndicatedshannon/F5c6T/
And here is another version with explicit viewport elements just to clarify, matching colors, and borders added to replicate the OP graphics (although per the OP the black border is actually the window).
Sample HTML
<html>
<body>
<div class="background"></div>
<div class="content"></div>
<div class="header"></div>
<div class="footer"></div>
</body>
</html>
Sample CSS
html { position: absolute; height: 100%; left: 10px; right: 10px; overflow: auto; margin: 0; padding: 0; }
body { position: relative; width: 100%; min-height: 100%; margin: 0; padding: 0; }
.background { position: absolute; top: 120px; bottom: 120px; background-color: red; width: 100%; }
.content { position: relative; padding: 120px 0; }
.header { position: absolute; top: 10px; height: 100px; width: 100%; background-color: yellow; }
.footer { position: absolute; bottom: 10px; height: 100px; width: 100%; background-color: cyan; }
Also note that this assumes you cannot rely on CSS3 yet.
If you're only targeting modern browsers, you can use calc()
body, html {
height: 100%;
padding: 0;
margin: 0;
}
.header {
height: 50px;
margin-bottom: 10px;
}
.footer {
height: 100px;
margin-top: 20px;
}
.content {
min-height: calc(100% - 50px - 10px - 100px - 20px);
}
The drawback is that you need to know the header and footer sizes and they need to be fixed. I don't know any way around this without using Javascript. For slightly less modern browsers, you can use border-box to get the same effect as above.
body, html {
height: 100%;
padding: 0;
margin: 0;
}
.header {
height: 50px;
margin-bottom: 10px;
z-index: 5;
position: relative;
}
.footer {
height: 100px;
margin-top: -100px;
z-index: 5;
position: relative;
}
.content {
box-sizing: border-box;
padding: 60px 0 120px 0;
margin-top: -60px;
min-height: 100%;
z-index: 1;
position: relative;
}
Lastly, here is the JS solution:
$(function(){
$('.content').css('min-height',
$(window).height()
- $('.header').outerHeight()
- $('.footer').outerHeight() - $('.content').marginTop()
- $('.content').marginBottom());
});
EDIT: My JS solution assumed border-box and no border. This solution should be more robust:
function setContentSize() {
$('.content').css('min-height',
$(window).height()
- $('.header').outerHeight()
- $('.footer').outerHeight()
- ($('.content').outerHeight()
- $('.content').innerHeight()));
}
$(setContentSize);
$(window).on('resize', setContentSize);