CSS – Header in display: table element – positioning issue - html

While creating a HTML layout, I noticed some strange positioning issue I was unable to solve.
Take the following HTML:
<div class="outer-wrap">
<div class="header">
I am a Header
</div>
<div class="element">
Hello world
</div>
And combine with this CSS code:
#import "https://cdnjs.cloudflare.com/ajax/libs/normalize/3.0.2/normalize.css";
html, body { height: 100%; }
.outer-wrap {
width: 100%;
height: 100%;
display: table;
background: grey;
}
.element {
display: table-cell;
vertical-align: middle;
background: blue;
}
.header {
position: absolute;
background: red;
}
Fiddle
As you can see, I've set the wrapper to display: table, which enables me to vertically center any child element with setting display: table-cell and vertical-align: middle.
Now when I try to add a header, strange things start to happen.
First, I have to declare position: absolute on the header, otherwise the header horizontally pushes away .element. I don't know why this happens, but I understand why this fix works: Because position: absolute takes things 'out of the flow'.
But if I take a look at the Fiddle, you'll notice a small gap on the left side which exposes the grey background color defined on .outer-wrap:
What is causing this gap & how to fix this?
Why do I have to use absolute positioning on the header to make it expand to the full container width?

The key reason causing that is you're not defining the table-cell div and would not be 100% wide and you see its shifting towards right seeing the gray border color which is the background of outer-wrap div. So, you need to define the width:100%; when you use display:table-cell; to make it display correctly.
Changed css:
.outer-wrap {
width: 100%;
height: 100%;
display: table;
background: grey;
}
.element {
display: table-cell;
vertical-align: middle;
background: blue;
width: 100%;/*explicitly define width to be 100%*/
}
.header {
position: absolute;
background: red;
z-index: 1;/*to make it display in front*/
}
Fixed fiddle

Related

Move divs vertically within a larger div

I am making an animation that involves a set of four divs inside one larger div. The four divs are too large to all fit in the one div at once, so I want to be able to specify the position at which the larger div should start. For example, here I have four boxes inside the div. From top to bottom, the boxes are green, purple, pink, and blue (you can't see the blue in the current jsfiddle because it is cut off). I would like the BOTTOM of the larger fulldisplay div to align with the MIDDLE of the blue box, and everything else to fit above hat until it is cut off at the top of the div. Eventually I am going to be implementing a custom-made scroll button (as I don't want it to look like the overflow:scroll one) but for now I am just trying to get CSS to display the inner divs the way I want.
JS FIDDLE: http://jsfiddle.net/o33gw35w/
CSS:
body {padding: 0; margin: 0; height: 100%; overflow: hidden; font-family: Helvetica;}
.nameblock {
height:10%;
width: 30%;
position: absolute;
background-color: yellow;
}
.fulldisplay {
height:90%;
width: 30%;
position: absolute;
overflow: hidden ;
}
.spacer1 {
height:40%;
position: relative;
background-color: green;
}
.spacer2{
height:40%;
position: relative;
background-color: purple;
}
.spacer3 {
height:40%;
position: relative;
background-color: pink;
}
.spacer4{
height:40%;
position: relative;
background-color: blue;
}
HTML:
<div class="nameblock"></div><br/>
<div class="fulldisplay">
<div class="spacer1">
</div>
<div class="spacer2">
</div>
<div class="spacer3"></div>
<div class="spacer4"></div>
</div>
</body>
Apologize if I got the question wrong as I am not quite sure what you are trying to do, but if you want to have a way of ordering s dynamically, you could use css flexbox to do so. You might need to tweak the classes to have correct width and height (eg. width: 100%; height: 150px;) and define flex container as similar to below snippet.
.fullconversation {
padding: 0;
margin: 0;
list-style: none;
width: 30%;
display: flex;
flex-direction: row;
-webkit-flex-flow: row wrap;
justify-content: space-around;
}
and then
.spacer4{
width: 100%;
height: 150px;
position: relative;
background-color: blue;
order: -1;
}
For more information about flexbox, please refer to the urls below or feel free to ask any questions regarding flexbox or css. Hope this helps.
https://css-tricks.com/almanac/properties/o/order/
https://css-tricks.com/snippets/css/a-guide-to-flexbox/
***********Updated************
If you change the height of spacer1 to be 10%, then you will see the blue box visible at the bottom. Note that the value 10% is just an example, as long as the total size of the heights of inner s dose not take up more than 100%, the blue box will be visible.
.spacer1 {
height:10%;
position: relative;
background-color: green;
}
Also, if you want to see all divs regardless of the size, you could just set overflow to other than hidden.

How do i make this layout in css, divs are collapsing

JsFiddle: http://jsfiddle.net/techsin/csfvb91u/
(just realized normal div is collapsing ALSO to size of content, is min height completely useless?)
I need two divs, one left, and on right. Left one is 100px wide and stays that way. While, right div expands infinitely and doesn't shrink beyond 400px. Both Divs should be the height of parent. And parent has no exact height but minimum height of 800. So if content of one of these 2 divs were to push the height of div and extend it. Then The height of parent should increase and thus also the height of other div.
I tried using floats. I managed to some extent. However left side which was on float left, its height kept collapsing and didn't follow height:100% rule. It only worked if parent had definite width.
I tried using inline block but then right div won't expand to fillin the available space..
Why in the world css doesn't have fit-content, fill-available, choose what % refers to, choose what to position against, use vector or use pngs to shape div, inset textshadow, etc.
<div class="cont">
<div class="a"></div>
<div class="b"></div>
</div>
try with display:table and display:table-cell for child you will need to give fixed with for the left div
demo - http://jsfiddle.net/z90fma6e/
html,
body {
height: 100%;
}
* {
margin: 0;
padding: 0;
}
.cont {
display: table;
height: 100%;
}
.left,
.right {
height: 100%;
}
.left {
width: 200px;
background: red;
display: block;
}
.right {
width: 100%;
display: table-cell;
background: green;
}
<div class="cont">
<div class="left">fixed
<br/>height adjusts</div>
<div class="right">expands
<br/>height adjusts</div>
</div>
Sounds like your divs are collapsing. Your going to need a clearfix you can add to divs. There are a few ways to do this; however, this option is best.
.clearfix:after {
content: ".";
visibility: hidden;
display: block;
height: 0;
clear: both;
}
Add this clearfix class and css to your divs so they wont collapse.
You can read more about them at cssTricks
perfect use case for CSS flex layout:
<style>
body {
display: flex;
flex-direction: row;
margin: 0;
padding: 0;
}
div:first-child {
width: 200px;
background: red;
}
div:last-child {
flex: 1;
background: blue;
}
</style>
<div></div>
<div></div>
If you wish to support IE8 or earlier I would suggest you to use positioning:
Here's what I came up with
Fiddle : http://jsfiddle.net/csfvb91u/4/
If the content on the right is going out of the container, you can always use margin-right:200px as the right side container is shifted 200px using left:200px. Hope you get what I'm saying... :)
HTML:
<div class="cont">
<div class="a"></div>
<div class="b"></div>
</div>
CSS:
.a {
position:absolute;
width: 200px;
background-color: green;
height: 100%;
}
.b {
width:100%;
position:absolute;
left:200px;
background-color: blue;
height: 100%;
}
.cont {
position:relative;
border:1px solid #333;
min-height:300px;
overflow:hidden;
}

Vertical alignment in CSS with position: absolute

I've got some questions about CSS text alignment that I am having some difficulty understanding. The best resource I've found about vertically aligning text via CSS is this: http://blog.themeforest.net/tutorials/vertical-centering-with-css/
I have a fiddle demonstrating some ways to vertically align text, and I'd appreciate if someone gave a quick answer.
http://jsfiddle.net/zSCJr/6/
I am curious why this text is not bottom aligned in container2's child, and have 5 quick questions in the JSfiddle.
HTML:
<div class="container container2">
container2
<div class="parent">
parent
<span class="child">
child<br/>
child
</span>
</div>
</div>
CSS:
.parent {
border: 1px solid green;
height: 50%;
}
.child {
border: 1px solid red;
vertical-align: bottom;
}
.container {
border: 1px solid black;
height: 150px;
margin-bottom: 40px;
}
.container1 .parent, .container2 .parent {
display: table;
}
.container1 .child, .container2 .child {
display: table-cell;
}
.container2 {
position: relative;
}
.container2 .parent {
width: 100%;
}
.container2 .child {
position: absolute;
right: 0;
top: 0;
bottom: 0;
}
I tried to reply at what I understand to your questions.
However, if you have an image result of what you want, it will be easier to us to give you the code or tell you how to achieve what you want.
Here is the JSFIDDLE where I put your questions answer.
Questions
1) removing position: absolute from container2's child makes the text align to the bottom (as expected from vertical-align: bottom). why?
2) container3's child,child,child span only gets clipped clipped by the first ancestor which has overflow:hidden AND position:something. why is position required?
3) container4's child does not stretch vertically unless position: absolute is set (position: relative will not do anything).
4) container4's child's height: 100% will use the first parent that has a position set. why not the first parent's content height?
5)container4's child has vertical-align: bottom set. But its text is not aligned to the bottom (unlike in container1 where parent has display: table and child has display: table-cell.
Answers
1)
On your css, you can reveiw that .container2 .child and .child css is applicated to your class, so removing only one vertical align on one class will still stick the table content to the bottom because .container2 .child is display as table cell
2)
I don't understand your question, what don't you don't understand?
If you have an image result of what you want, I can code it and you will learned from it.
3)
Inside a table, everything is managed differently, you need to define how to display your content. You need to aply display: block to .container4 .child
4)
Because you have the choice =)
So set the parent position of the item that you want
5)
Because you forgot to add .container4 .parent {display: table;} and .container4 .child {display: table-cell;}
Hope this help =)

CSS help positioning divs inline

I need help with a recurring problem that happens a lot. I want to create a header that consists of 3 sections which are positioned inline. I display them inline using the following css code: display: inline & float: leftThe problem is that when I resize my browser window the last div is pushed down and isn't displayed inline. I know it sounds like I'm being picky, but I don't want the design to distort as the visitor change's the monitor screen. I have provided the html and css code below that I am working with below. Hopefully I have explained this well enough. Thanks in advance.
HTML
<div class="masthead-wrapper">
</div>
<div class="searchbar-wrapper">
</div>
<div class="profile-menu-wrapper">
</div>
CSS
#Header {
display: block;
width: 100%;
height: 80px;
background: #C0C0C0;
}
.masthead-wrapper {
display: inline;
float: left;
width: 200px;
height: 80px;
background: #3b5998;
}
.searchbar-wrapper {
display: inline;
float: left;
width: 560px;
height: 80px;
background: #FF0000;
}
.profile-menu-wrapper {
display: inline;
float: left;
width: 200px;
height: 80px;
background: #00FF00;
}
display them inline using the following css code: display: inline & float: left
Aside... You are actually floating the element, not displaying it inline. The display:inline rule is irrelevant here since floated elements are implicitly displayed as block.
But anyway, your problem is that your sections are all of a fixed width (200 + 560 + 200 = 960px), so when the browser window reduces to near this width (960px plus a bit more for your page margins) the design is going to break - your containers wrap.
If you still want these containers to be fixed width and to simply be cropped on a smaller browser window then you could perhaps add overflow:hidden to your #Header. At least then it won't push the #Header height down beyond 80px (which is a problem you seem to be experiencing). But content will be hidden on the smaller screen.
Or, make all your column containers dynamic and give them percentage widths, so that they flex with the available width. eg. 20%, 60% and 20% respectively. Although this might make the widths too small or too large at some window sizes. You could add a min-width and max-width (with an absolute amount) to limit this. But at narrow widths height:80px is not going to be enough, so min-height:80px would perhaps be more appropriate, if your design allows for your #Header to be flexible?
With the percentage, be sure to no have padding on your columns. The padding will be add some width. For your header, you can use the position:fixed, and for IE6 and 7 use position: absolute ( the position :fixed ) doesn't work for them.
For the columns, you can add the clearfix method who can help you for placing without problem the rest of the content.
Your HTML can be something like this :
<div id="header" class="clearfix">
<div id="col01">Column 01</div>
<div id="col02">Column 02</div>
<div id="col03">Colunm 03</div>
</div>
And the CSS :
#header {
position: fixed;
height:80px;
width:100%;
}
#col01,
#col02,
#col03 {
float:left;
}
#col01,
#col03 {
width:20%;
}
#col02 {
width:60%;
}
.clearfix:after {
content: ".";
display: block;
clear: both;
visibility: hidden;
line-height: 0;
height: 0;
}
.clearfix {
display: inline-block;
}
html[xmlns] .clearfix {
display: block;
}
* html .clearfix {
height: 1%;
}
Hope it's helping you :-)

Converting to tableless layout

I'm currently using 1 table to align 2 main portions of the site. It's causing problems for me now, so I'd like to use pure CSS.
I have a 205px wide navbar column on the left. Occupying the rest of the space on the right, I'd like to have a container (So on the right side of the screen, taking up screen width - 200 pixels) This container would not have a fixed height, but I want its top to be aligned with the top of the navbar.
Here's a demo of what I currently have .
I would like the solution to be similar to that, but not use tables, and have the top of the container aligned with the top of the sidebar.
I've made several attempts at doing this (before I started using the table, and after) but none of them even remotely worked. I've come here as a last resort, so I hope that someone could help.
Fiddle
.container{height: 100%; border: 1px solid #0f0; display: table;}
#sidebar{
width:40%; height: 100%; display: table-cell; background: #ccc;
}
#sidebar2{
width:60%; height: 100%; display: table-cell; background: #f00;
}
body, html {
height:100%;
}
HTML
<div class="container">
<div id="sidebar">links and whatnot go here</div>
<div id="sidebar2">this is the container (but its top is not aligned with the sidebar as I would like)</div>
</div>
Note: table-cell property is supported by supports IE8+
EDIT:
If you can't use table-cell then you have to use some jquery to calculate height. Check this Fiddle
I would do something like this:
. HTML:
<div id="container">
<aside id="sidebar">Links and whatnot</aside>
<section id="content">Content and whatnot</section>
</div>
. CSS:
html, body {
width: 100%;
height: 100%;
}
div#container {
height: 100%;
}
aside#sidebar {
background-color: #f00;
width: 205px;
min-height: 100%;
float: left;
}
section#content {
background-color: #0f0;
min-height: 100%;
}
You can see it working in this fiddle.