white-space: nowrap seems to affect inner elements position: absolute - html

I want to have a horizontal list of items, contained in a horizontally scrollable outer-wrapper with a fixed width. The outer-wrapper has a relative position. One of the items contains an absolute positioned div.
When scrolling the outer-wrapper, I was expecting the green overlay to remain at the same position. I thought position: absolute is always relative to the first ancestor with a defined position (which would be the outer-wrapper)?
I am using white-space: nowrap for the #wrapper to get the items in a row.
#outer-wrapper {
position: relative;
width: 300px;
height: 150px;
overflow: scroll;
}
#wrapper {
white-space: nowrap;
display: inline-block;
}
#one {
background-color: red;
}
#two {
background-color: blue;
}
.box {
white-space: normal;
display: inline-block;
width: 200px;
height: 150px;
}
.overlay {
background-color: green;
position: absolute;
bottom: 0px;
left: 0px;
width: 100%;
height: 40px;
}
<div id="outer-wrapper">
<div id="wrapper">
<div id="one" class="box">
<div class="overlay"></div>
</div>
<div id="two" class="box"></div>
</div>
</div>
I'd like the markup to remain as it is in the example, although this is not totally fixed.
And I can't really define a fixed width for the horizontal list.

If I've got your question correctly then it is not possible with only HTML and CSS. However you can achieve it with jQuery as follows:
$(function() {
var wrapper = $('#outer-wrapper');
$('#outer-wrapper').scroll(function() {
$('.overlay').css({
'marginLeft': wrapper.scrollLeft()
});
});
});
#outer-wrapper {
position: relative;
width: 300px;
height: 150px;
overflow: scroll;
}
#wrapper {
white-space: nowrap;
display: inline-block;
}
#one {
background-color: red;
}
#two {
background-color: blue;
}
.box {
white-space: normal;
display: inline-block;
width: 200px;
height: 150px;
}
.overlay {
background-color: green;
position: absolute;
bottom: 0px;
left: 0px;
width: 100%;
height: 40px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="outer-wrapper">
<div id="wrapper">
<div id="one" class="box">
<div class="overlay"></div>
</div>
<div id="two" class="box"></div>
</div>
</div>

Related

How To Make Div With 100% Height Extend into Scroll Overflow in HTML/CSS?

I have a div in HTML that has two child divs, one on the right and one on the left. Both child divs have contenteditable set, so when the user click in them they can type. However, when the text goes below the size of the div, the parent div overflows and scrolls, but the child divs don't.
Here is an example:
#container {
width: 300px;
height: 200px;
border: 1px solid black;
overflow: scroll;
color: white;
background: gray;
}
#part1 {
width: 50%;
margin: 0;
background: blue;
height: 100%;
float: left;
overflow: visible;
}
#part2 {
width: 50%;
margin: 0;
background: green;
height: 100%;
float: right;
overflow: visible;
}
<div id="container">
<div id="part1" contenteditable="true"></div>
<div id="part2" contenteditable="true"></div>
</div>
In the above example, try typing more text than can fit vertically (by spamming the enter key while inside the box). Once the text goes over the side of the box, the parent overflows like it is supposed to, however, the children (which are being typed into) don't, even though they have 100% height.
Is there a way to make the children extend WITH the parent, so they both scroll together when one/both overflows?
It is very good for your task to use the rules of flexibility. Add display: flex and flex-flow: wrap for #container. And remove the height: 100% from the children, because flex-flow: wrap itself will stretch the elements to the full height.
Also, remove float: left and overflow: visible from children.
#container {
width: 300px;
height: 200px;
border: 1px solid black;
overflow: scroll;
color: white;
background: gray;
display: flex;
flex-flow: wrap;
}
#part1 {
width: 50%;
margin: 0;
background: blue;
/*height: 100%;
float: left;
overflow: visible;*/
}
#part2 {
width: 50%;
margin: 0;
background: green;
/*height: 100%;
float: right;
overflow: visible;*/
}
<div id="container">
<div id="part1" contenteditable="true"></div>
<div id="part2" contenteditable="true"></div>
</div>
You could change height to min-height for the inner divs and use an additional inner div with display: flex so that both colored divs have the same growing height. overflow: visible is not necessary.
Working example:
#container {
width: 300px;
height: 200px;
border: 1px solid black;
overflow: scroll;
color: white;
background: gray;
}
#inner {
display: flex;
min-height: 200px;
}
#part1 {
width: 50%;
margin: 0;
background: blue;
min-height: 100%;
float: left;
}
#part2 {
width: 50%;
margin: 0;
background: green;
min-height: 100%;
float: right;
}
<div id="container">
<div id="inner">
<div id="part1" contenteditable="true"></div>
<div id="part2" contenteditable="true"></div>
</div>
</div>
Since you define some css twice and overflow-x is not necessary you can add a class to the colored divs and set the overflow for the container only to overflow-y.
Working example:
#container {
border: 1px solid black;
width: 300px;
height: 200px;
color: white;
background: gray;
overflow-y: scroll;
}
#inner {
display: flex;
min-height: 200px;
}
.editable {
width: 50%;
margin: 0;
min-height: 100%;
}
#part1 {
background: blue;
float: left;
}
#part2 {
background: green;
float: right;
}
<div id="container">
<div id="inner">
<div class="editable" id="part1" contenteditable="true"></div>
<div class="editable" id="part2" contenteditable="true"></div>
</div>
</div>

Second DIV on all remaining space

I want to create two divs, one under other without JS and with IE8 support.
Each has 100% width.
Each with relative or absolute positioning for nested layout.
Top div have height by content, not fixed (it is important) and bottom div on whole leftover space.
In my example bottom div is too short, how i can stretch it to bottom?
<html>
<head>
<style type="text/css"><!--
* {
padding: 1px;
margin: 0px;
border: solid 1px;
width: 100%;
}
#super {
position: absolute;
height: 100%;
}
#top {
position: relative;
}
#bottom {
position: relative;
top: 0px;
bottom: 0px;
}
--></style>
</head>
<body>
<div id="super">
<div id="top">top</div>
<div id="bottom">bottom</div>
</div>
</body>
</html>
You can use css table properties to create this layout.
HTML:
<div id="super">
<div id="top">
<div class="content">
top
</div>
</div>
<div id="bottom">
<div class="content">
bottom
</div>
</div>
</div>
Necessary CSS:
html,
body {
height: 100%;
}
#super {
height: 100%;
width: 100%;
display: table;
}
#super > div {
display: table-row;
}
#top {
background: green;
}
#bottom {
background: blue;
}
html,
body {
height: 100%;
padding: 0;
margin: 0;
}
#super {
height: 100%;
width: 100%;
display: table;
}
#top {
background: green;
overflow: hidden;
height: 1%;
}
.content {
padding: 10px;
}
#bottom {
background: blue;
}
#super > div {
display: table-row;
}
<div id="super">
<div id="top">
<div class="content">
top
</div>
</div>
<div id="bottom">
<div class="content">
bottom</div>
</div>
</div>
Output Image:
You can use display: table for wrapping container and table-row for top and bottom divs:
* {
padding: 1px;
margin: 0px;
border: solid 1px;
width: 100%;
}
#super {
display: table;
position: absolute;
height: 100vh;
}
#top {
display: table-row;
height: 1px;
position: relative;
background: orange;
}
#bottom {
display: table-row;
position: relative;
top: 0px;
bottom: 0px;
background: teal;
}
<div id="super">
<div id="top">top<br>top text</div>
<div id="bottom">bottom</div>
</div>
Use flex-box
.parent{
display: flex;
flex-direction: column;
min-height: 100vh
}
.child2{
flex: 1;
background: blue;
}
<div class="parent">
<div class="child1"> first child</div>
<div class="child2"> second child</div>
</div>
Demo here
Try this :
#bottom {
position: relative;
top: 0px;
bottom: 0px;
HEIGHT: 800px;
}

Positioning a div at the bottom of a “absolute” <div>

I'm having troubles positioning my divs. I want to have my child div stick to the bottom of the parent div, with grandchild_1 and grandchild_2 staying correctly put. By that, I mean having grandchild_1 before grandchild_2, like on the picture.
This is what I've tried, but the "child" div sticks to the top :
#parent {
position: relative;
}
#child {
position: absolute; bottom: 0;
}
<div id="parent">
<div id="child">
<div id="grandchild_1">
</div>
<div id="grandchild_2">
</div>
</div>
</div>
Anyone knows how I should proceed ? Thanks !
If you specify a height on the parent it will stick to the bottom.
Example: http://codepen.io/anon/pen/wGqzVd
HTML
<div id="parent">
Parent
<div id="child">
Child
<div id="grandchild_1">
Grandchild 1
</div>
<div id="grandchild_2">
Grandchild 2
</div>
</div>
</div>
CSS
div {
padding: 5px;
}
#parent {
position: relative;
background: lightgray;
height: 200px;
width: 150px;
}
#child {
position: absolute;
bottom: 5px;
background: yellow;
}
#grandchild_1 {
background: pink;
}
#grandchild_2 {
background: lightblue;
}
The provided code works as is...assuming that the parent has a height greater than that of the child.
#parent {
position: relative;
height: 200px;
background: pink;
}
#child {
position: absolute;
width: 100%;
bottom: 0;
background: green;
}
#grandchild_1,
#grandchild_2 {
height: 25px;
background: red;
margin: 10px;
}
<div id="parent">
<div id="child">
<div id="grandchild_1">GC1
</div>
<div id="grandchild_2">GC2
</div>
</div>
</div>
As an alternative to positioning, flexbox can do the same...and the child will affect the height of the parent which an absolutely positioned child cannot.
#parent {
position: relative;
height: 200px;
background: pink;
display: flex;
flex-direction: column;
justify-content: flex-end;
}
#child {
width: 100%;
background: green;
}
#grandchild_1,
#grandchild_2 {
height: 25px;
background: red;
margin: 10px;
}
<div id="parent">
<div id="child">
<div id="grandchild_1">GC1
</div>
<div id="grandchild_2">GC2
</div>
</div>
</div>

What's causing this resizable div to overflow its 100% height container?

If you drag the resizeable yellow div up to its maximum possible height, it will overflow and a scrollbar is displayed.
html, body {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
.container {
height:100%;
width: 100%;
background-color: red;
display: table;
}
.header {
background-color: green;
height:100%;
display: table-row;
}
.content {
width:100%;
height: auto;
background-color:white;
display: table-row;
}
.control {
resize: vertical;
overflow: auto;
background-color: yellow;
}
<div class="container">
<div class="header"> </div>
<div class="content">
<div class="control"> </div>
</div>
</div>
What's causing this and how can I prevent it?
It's because the yellow box keeps getting bigger until it overflows the container; you can prevent this using CSS max-height: 100%. The problem with this is that the container keeps expanding as the yellow box expands, so the yellow box never actually fills the available space. I fixed this by giving the container position: relative and the resizable control position: absolute.
html, body {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
.container {
height:100%;
width: 100%;
background-color: red;
display: table;
position: relative;
}
.header {
background-color: green;
height:100%;
display: table-row;
}
.content {
width:100%;
height: auto;
background-color:white;
display: table-row;
}
.control {
position: absolute;
bottom: 0;
height: 20px;
left: 0;
right: 0;
resize: vertical;
overflow: auto;
background-color: yellow;
max-height: 100%;
}
<div class="container">
<div class="header"> </div>
<div class="content">
<div class="control"> </div>
</div>
</div>

display div elements in parent with overflow hidden

I have a div with class container. I have 3 more divs inside .container. What I want is to display internal divs float: left so that 2 divs tags are visible inside .container and the third one is invisible and is placed on the right side of first 2 div tags which are visible. I am trying the following code but it makes all tags visible all the time.
jsfiddle
<div class="container">
<div class="div"></div>
<div class="div"></div>
<div class="div"></div>
</div>
css
.container {
position: relative;
width: 405px;
height: 500px;
background: red;
margin: 0 auto;
overflow: hidden;
}
.div {
width: 200px;
height: 200px;
background: blue;
float: left;
border: 1px solid red;
}
I want above to look like this
You can do as such in other way,
HTML
<div class="container">
<div class="innerContainer">
<div class="div"></div>
<div class="div"></div>
<div class="div"></div>
</div>
</div>
CSS
.container {
position: relative;
width: 405px;
height: 500px;
background: red;
margin: 0 auto;
overflow: hidden;
}
.innerContainer {
position: relative;
width: 605px;
height: 500px;
overflow: hidden;
}
.div {
width: 200px;
height: 200px;
background: blue;
float: left;
border: 1px solid red;
}
Check over here http://jsfiddle.net/nftp6/8/
Use:
display: inline-block;
white-space: nowrap;
For that effect
Fiddle:
http://jsfiddle.net/Hive7/nftp6/5/
Use display:inline-block instead of float and set white-space:nowrap to the container:
.container {
position: relative;
width: 405px;
height: 500px;
background: red;
margin: 0 auto;
overflow: hidden;
white-space: nowrap;
}
.div {
width: 200px;
height: 200px;
background: blue;
display: inline-block;
border: 1px solid red;
}
Demo fiddle
Now you'll most likely face some white-space issues, read this answer for multiple ways to handle that