CSS - Position absolute overflow parent while being able to scroll - html

I am trying to have a load of divs which are horizontal scrolled. Each div is absolute positioned (the red box in my example) so that it is visible outside of the scrolling container. I have an example that works well but seems I have lost the ability to scroll. The scroll bar appears but scrolling it does not move the divs.
By adding position relative to the overall container I can get the divs to scroll, but they don't show outside of the container.
Please help me be able to show contents outside of container yet maintain scrollability.
<div style="overflow-x:scroll; height:40px; white-space: nowrap; background:black;">
<div style="display:inline-block; margin-left:50px; width:500px; height:40px">
<div style="border:1px solid black; height:40px; width:500px; position:absolute">
<div style="position:absolute; height:100px;width:500px; background:Red; top:5px; left:5px"></div>
</div>
</div>
<div style="display:inline-block; margin-left:50px; width:500px; height:40px">
<div style="border:1px solid black; height:40px; width:500px; position:absolute">
<div style="position:absolute; height:100px;width:500px; background:Red; top:5px; left:5px"></div>
</div>
</div>
<div style="display:inline-block; margin-left:50px; width:500px; height:40px">
<div style="border:1px solid black; height:40px; width:500px; position:absolute">
<div style="position:absolute; height:100px;width:500px; background:Red; top:5px; left:5px"></div>
</div>
</div>
<div style="display:inline-block; margin-left:50px; width:500px; height:40px">
<div style="border:1px solid black; height:40px; width:500px; position:absolute">
<div style="position:absolute; height:100px;width:500px; background:Red; top:5px; left:5px"></div>
</div>
</div>
<div style="display:inline-block; margin-left:50px; width:500px; height:40px">
<div style="border:1px solid black; height:40px; width:500px; position:absolute">
<div style="position:absolute; height:100px;width:500px; background:Red; top:5px; left:5px"></div>
</div>
</div>
</div>

I slightly edited your code snippet and added a class to the black container, to easily style its direct children with this:
.container > div {
border: 1px solid green;
}
.container > div {
border: 1px solid green;
}
<div class="container" style="overflow-x:scroll; height:40px; white-space: nowrap; background:black;">
<div style="display:inline-block; margin-left:50px; width:500px; height:40px">
<div style="border:1px solid black; height:40px; width:500px; position:absolute">
<div style="position:absolute; height:100px;width:500px; background:Red; top:5px; left:5px"></div>
</div>
</div>
<div style="display:inline-block; margin-left:50px; width:500px; height:40px">
<div style="border:1px solid black; height:40px; width:500px; position:absolute">
<div style="position:absolute; height:100px;width:500px; background:Red; top:5px; left:5px"></div>
</div>
</div>
<div style="display:inline-block; margin-left:50px; width:500px; height:40px">
<div style="border:1px solid black; height:40px; width:500px; position:absolute">
<div style="position:absolute; height:100px;width:500px; background:Red; top:5px; left:5px"></div>
</div>
</div>
<div style="display:inline-block; margin-left:50px; width:500px; height:40px">
<div style="border:1px solid black; height:40px; width:500px; position:absolute">
<div style="position:absolute; height:100px;width:500px; background:Red; top:5px; left:5px"></div>
</div>
</div>
<div style="display:inline-block; margin-left:50px; width:500px; height:40px">
<div style="border:1px solid black; height:40px; width:500px; position:absolute">
<div style="position:absolute; height:100px;width:500px; background:Red; top:5px; left:5px"></div>
</div>
</div>
</div>
Now you should be able to see that the scrolling is actually working, but only for the green divs. The other elements (black border divs and red divs) are not scrolling because they have position: absolute;. This means that they are taken out of the document flow and since no other element has position: relative, they are absolute relative to the body. That's why, if you scroll with the main scrollbar, they will actually scroll.
You could add position: relative; to the container, but doing so, as you said, the elements won't overflow the container.
As far as I know, there's no way to solve this with just css and you probably have to make them scroll through some Javascript.
A very basic example:
const container = document.querySelector('.container');
const boxes = document.querySelectorAll('.box');
container.addEventListener('scroll', (e) => {
let offset = e.target.scrollLeft;
for(let box of boxes) {
box.style.transform = `translateX(${offset}px)`;
}
});
.container > div {
border: 1px solid green;
}
.fake-width {
width: 2000px;
}
.boxes {
display: flex;
}
.box {
background: blue;
}
.box + .box {
margin-left: 50px;
}
<div class="container" style="overflow-x:scroll; height:40px; white-space: nowrap; background:black;">
<div class="fake-width"></div>
</div>
<div class="boxes">
<div class="box box-1" style="display:inline-block; margin-left:50px; width:500px; height:40px">
</div>
<div class="box box-2" style="display:inline-block; margin-left:50px; width:500px; height:40px">
</div>
<div class="box box-3" style="display:inline-block; margin-left:50px; width:500px; height:40px">
</div>
</div>
</div>
As you can notice, if you go this route, you don't even need to keep the divs inside the scrolling container. You could, depending on what exactly you are going to build, but you don't need to.

Related

100% width/height absolute parent with padding

My goal is to have a container that fills up it's parent with some padding like you see in the blow snippet. Right now the only way I could figure out how to accomplish this is with calc(). And since calc technically has a better browser support then flex, I'd like to stay away from that.
Can anyone see a way to accomplish this without javascript and with calc()?
Assume that all width's are percentages.
* { box-sizing: border-box;}
.box {
position:relative;
margin:5px;
}
.halfBox {
padding-bottom:100%;
border:1px solid red;
}
.fullBox {
padding-bottom:50%;
border:1px solid red;
}
.content {
font-size:12px;
background-color:#e3e3e3;
position:absolute;
width:calc(100% - 20px);
height:calc(100% - 20px);
left:10px;
top:10px;
}
<div style="font-size:0">
<div style="width:200px;display:inline-block;">
<div class="halfBox box">
<div class="content">
1
</div>
</div>
</div>
<div style="width:400px;display:inline-block;">
<div class="fullBox box">
<div class="content">
1
</div>
</div>
</div>
</div>
Simply use top/left like you did and right/bottom
* { box-sizing: border-box;}
.box {
position:relative;
margin:5px;
}
.halfBox {
padding-bottom:100%;
border:1px solid red;
}
.fullBox {
padding-bottom:50%;
border:1px solid red;
}
.content {
font-size:12px;
background-color:#e3e3e3;
position:absolute;
right:10px;
bottom:10px;
left:10px;
top:10px;
}
<div style="font-size:0">
<div style="width:200px;display:inline-block;">
<div class="halfBox box">
<div class="content">
1
</div>
</div>
</div>
<div style="width:400px;display:inline-block;">
<div class="fullBox box">
<div class="content">
1
</div>
</div>
</div>
</div>
You can also consider margin too:
* { box-sizing: border-box;}
.box {
position:relative;
margin:5px;
}
.halfBox {
padding-bottom:100%;
border:1px solid red;
}
.fullBox {
padding-bottom:50%;
border:1px solid red;
}
.content {
font-size:12px;
background-color:#e3e3e3;
position:absolute;
right:0;
bottom:0;
left:0;
top:0;
margin:10px;
}
<div style="font-size:0">
<div style="width:200px;display:inline-block;">
<div class="halfBox box">
<div class="content">
1
</div>
</div>
</div>
<div style="width:400px;display:inline-block;">
<div class="fullBox box">
<div class="content">
1
</div>
</div>
</div>
</div>

Why the `clear:both` can not written into div.box3?

I want margin-top:10px to be displayed on the top of box3.
Here is the proper codes on firefox.
<div class="clear"></div> was written as a single line before div box3,and
write div.clear{clear:both;} as a special part.
div.box{
width:105px;
height:200px;
border:1px solid red;
}
div.box1{
float:left;
width:50px;
height:50px;
border:1px solid red;
}
div.box2{
float:left;
width:50px;
height:50px;
border:1px solid red;
}
div.clear{
clear:both;
}
div.box3{
width:100px;
height:80px;
border:1px solid red;
margin-top:10px;
}
<body>
<div class="box">
<div class="box1">box1</div>
<div class="box2">box2</div>
<div class="clear"></div>
<div class="box3">box3</div>
</div>
</body>
Now i move clear:both; in the div.box3,the whole css code as below.
div.box{
width:105px;
height:200px;
border:1px solid red;
}
div.box1{
float:left;
width:50px;
height:50px;
border:1px solid red;
}
div.box2{
float:left;
width:50px;
height:50px;
border:1px solid red;
}
div.box3{
clear:both;
width:100px;
height:80px;
border:1px solid red;
margin-top:10px;
}
<body>
<div class="box">
<div class="box1">box1</div>
<div class="box2">box2</div>
<div class="clear"></div>
<div class="box3">box3</div>
</div>
</body>
No 10px at the top of div.box3.
I know right way to solve it ,want to know the principle behind the proper css code.

Fit content to div & center, with another centered div overlapping it... but not pushing content down

Basically I want to have something like this: http://i.stack.imgur.com/GwtOm.png
I want the div containing the headline to fit to the size of the headlines. I know this can be achieved with display:inline-block; or display:table-cell; but when I add another div that I want to overlap the line, it pushes everything down.
Not sure if there’s a way to avoid that or if there's a better way to get the effect I’m going for. Any suggestions are much appreciated!
Two code examples:
body,html {margin:0;border:0;padding:0; vertical-align: baseline; line-height: 1;
}
.banner {
width:600px;
height: 400px;
background-color:grey;
}
.outer {
display:table;
margin:0 auto;
background-color:pink;
position:relative;
}
.inner {
display:table-cell;
}
.top{
border-bottom: 2px black solid;
}
.top, .bottom{
padding:20px;
text-align:justify;
}
.overlap{
position:relative;
background-color:pink;
text-align:center;
top:65px;
z-index: 100;
line-height:1;
padding:0 10px;
}
.txty{
font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif;
font-size:16px;
}
<div class="banner">
<div class="outer">
<div class="inner">
<div class="overlap"><span class="txty">AND</span></div>
</div>
</div>
<div class="outer">
<div class="inner">
<div class="top">
<span class="txty">
Hi, this div fits to the content and it is horizontally centered, too.
</span>
</div>
<div class="bottom">
<span class="txty">
hey cool</span>
</div>
</div>
</div>
</div>
Or the other way I tried was this:
body {
background-color:grey;
margin:0;
}
.overr {
position:relative;
background-color:green;
display:inline-block;
text-align:center;
top:43px;
z-index: 100;
line-height:1;
padding:0 10px;
}
.outer {
text-align:center;
background-color:pink;
position:relative;
top:20px;
}
.inner1 {
display:inline-block;
background-color:green;
line-height:0;
}
.a{
border-bottom:4px solid black;
}
.b {
display:inline-block;
line-height:0;
}
<div class="outer">
<div class="overr">AND</div>
</div>
<div class="outer">
<div class="inner1">
<div class="a">
<p>hi, this div fits to the content and it is centered, too. Cool!</p>
</div>
<div class="b">
<p> test</p>
</div>
</div>
</div>
try position:absolute and adjust top and left
.overlap{
position:absolute;
background-color:pink;
text-align:center;
top:65px;
z-index: 100;
line-height:1;
padding:0 10px;
}
else apply float to the div and apply proper margins

How do I float divs next to each other?

I want the leftcol and rightcol divs to float next to each other. How do I do that?
#charset "utf-8";
/* CSS Document */
#container{width:100%; height:1000px; margin:auto; background-color:#00ffff;}
#header{width:95%; height:80px; margin:auto; margin-top:50px;}
#logo{width:10%; height:50px; margin-top:10px; margin-left:20px; float:left;}
#navbar{width:60%; height:50px; margin-top:10px; margin-right:10px; float:right;}
#maincontent{width:95%; height:70%; margin:auto; margin-top:15px;}
#leftcol{width:14%; height:30%; margin-left:15px; margin-top:20px; position:fixed;}
#rightcol{width:40%; height:30%;}
#charset "utf-8";
/* CSS Document */
#container{width:100%; height:1000px; margin:auto; background-color:#00ffff;border:1px solid black;}
#header{width:95%; height:80px; margin:auto; margin-top:50px;border:1px solid black;}
#logo{width:10%; height:50px; margin-top:10px; margin-left:20px; float:left;border:1px solid black;}
#navbar{width:80%; height:50px; margin-top:10px; margin-right:10px; float:right;border:1px solid black;}
#maincontent{width:95%; height:70%; margin:auto; margin-top:15px;border:1px solid black;}
#leftcol{width:14%; height:30%; margin-left:15px; margin-top:20px;border:1px solid black;display:inline-block;}
#rightcol{width:80%; height:30%;border:1px solid black;display:inline-block;}
<html>
<head></head>
<body>
<div id="container">
<div id="header">
<div id="logo">
#LOGO
</div>
<div id="navbar">
#NAVBAR
</div>
</div>
<div id="maincontent">
<div id="leftcol">
#leftcol
</div>
<div id="rightcol">
#rightcol
</div>
</div>
</div>
</body>
</html>
add this to your div css code it will make div's aligned
display:inline-block;

html css style not working

I am trying to place some text inside an image, but the text div is not coming on top of the image, rather it is hidden and invisible right below the image. thanks in advance!
Here is a link to jsfiddle:
http://jsfiddle.net/XrXZj/1/
have the following in my css file:
.spotlight {
color:#FFFFFF;
display:table;
height:120px;
margin-bottom:15px;
margin-left:0px;
overflow:hidden;
padding:0 50px;
position:relative;
width:840px;
}
.spotlight .wrapper {
position:absolute;
}
.spotlight .middle {
display:table-cell;
height:50px;
vertical-align:middle;
}
.spotlight .spotlight-copy {
font-size:15px;
line-height:25px;
width:500px;
}
and here is the content of html file:
<div class="spotlight">
<img src="<spring:url value="/assets/img/banner-natural-hazard-risk.jpg"/>" border="0" />
<div class="wrapper">
<div class="middle">
<div class="spotlight-copy">
<spring:message code="content.location.title" />
</div>
</div>
</div>
<div style="clear: both;"></div>
</div>
.spotlight .wrapper {
position:absolute;
top: 0;
}
I put there a solution http://jsfiddle.net/NPh76/
HTML is:
<div class="wrapper">
<div class="middle">
<div class="spotlight">
<img src="http://www.springsource.org/files/header/logo-spring-103x60.png" border="0" />
<div class="spotlight-copy">
message in spotlight copy
</div>
</div>
</div>
<div style="clear: both;"></div>
notice about HTML:
<IMG> is into .middle to be at same level as .spotlight-copy
CSS is:
.spotlight {
color:#FFFFFF;
display:table;
height:120px;
margin-bottom:15px;
margin-left:0px;
overflow:hidden;
padding:0 50px;
position:absolute;
width:840px;
}
.spotlight .wrapper {
position:absolute;
}
.spotlight .middle {
display:table-cell;
height:50px;
vertical-align:middle;
}
.spotlight .spotlight-copy {
position:absolute;
top: 0px;
font-size:15px;
line-height:25px;
width:500px;
color:#FF0000;
}
notice about CSS
position:absolute; in .spotlight-copy
top: 0px; for position
color:#FF0000; to see something ;)