Make an element overlap others when viewport runs out of room - html

I have the blue square that will contain things adding up to 800px.
I want the red square to always be fully visible. That is when you narrow the viewport, the red square should overlap the blue square, and not disappear on the right like it does actually.
How can I achieve that?
.container {
display: flex;
}
div {
height: 80px;
}
.should-be-overlapped {
width: 100%;
min-width: 800px;
background: blue;
}
.always-full-width {
width: 400px;
background: red;
}
<div class="container">
<div class="should-be-overlapped"></div>
<div class="always-full-width"></div>
</div>

To accomplish that, there is mainly 2 ways.
Either add a wrapper around the blue (which I recommend).
Updated codepen
Stack snippet
.container {
position: relative;
display: flex;
}
div {
height: 80px;
}
.wrapper {
flex: 1;
overflow: hidden;
}
.should-be-overlapped {
width: 100%;
min-width: 800px;
background: blue;
}
.always-full-width {
flex: 0 0 400px;
background: red;
}
<div class="container">
<div class="wrapper">
<div class="should-be-overlapped">
</div>
</div>
<div class="always-full-width">
</div>
</div>
Or use position: absolute.
Updated codepen
.container {
display: flex;
position: relative;
overflow: hidden;
}
div {
height: 80px;
}
.should-be-overlapped {
width: 100%;
min-width: 800px;
background: blue;
}
.always-full-width {
position: absolute;
right: 0;
width: 400px;
background: red;
}
.<div class="container">
<div class="should-be-overlapped">
</div>
<div class="always-full-width">
</div>
</div>

I have the blue square that will contain things adding up to 800px.
Then you should do it with the flex: 0 1 800px, which will enable it to shrink:
.container {
display: flex;
}
div {
height: 80px;
}
.should-be-overlapped {
/*min-width: 800px;*/
flex: 0 1 800px; /* doesn't grow but shrinks, initial width set to 800px (this is also its "max-width") */
background: blue;
word-break: break-all; /* for longer unbreakable strings, just for demo */
}
.always-full-width {
/*width: 400px;*/
flex: 0 0 400px; /* since you're using flexbox, doesn't grow nor shrink, initial width set to 400px (fixed) */
background: red;
}
<div class="container">
<div class="should-be-overlapped">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</div>
<div class="always-full-width"></div>
</div>

Related

HTML -> Fixed top, Flexible bottom with min-height and dynamic squared content

I'm really struggling to create css layout like this:
Top row: fixed size: Ex: 50px;
Content: the biggest square the current width can fit. So width = height for this one. It should respect the bottom row min-height.
Bottom row: take all remaining space available, and with min-height. Ex: 50px.
No scrollbar. The idea is to use the current screen the best way possible for any resolution. No javascript unless it's only possible with js.
Any ideas?
That's the best I've got so far:
<div class="shell">
<div class="header"></div>
<div class="square"></div>
<div class="footer"></div>
</div>
css
body {
margin: 0px;
}
.shell {
background-color: #000000;
height: 100vh;
max-width: calc(100vh - 100px);
overflow: hidden;
margin-left: auto;
margin-right: auto;
}
.header {
background-color: #0000ff;
height: 50px;
}
.square {
width: 100%;
background-color: #dc143c;
}
.footer {
background-color: #00008b;
height: 100vh;
}
You can use padding to get the aspect ratio:
body {
margin: 0px;
}
.shell {
background-color: #000000;
height: 100vh;
max-width: calc(100vh - 100px);
overflow: hidden;
margin-left: auto;
margin-right: auto;
}
.header {
background-color: blue;
height: 50px;
}
.square {
width: 100%;
padding-top: 100%;
background-color: green;
}
.footer {
background-color: red;
height: 100%;
}
<div class="shell">
<div class="header"></div>
<div class="square"></div>
<div class="footer"></div>
</div>
Reference here
I think your question was already solved here:
Make a div fill the height of the remaining screen space
Mixed with your try:
body {
margin: 0;
}
.box {
display: flex;
flex-flow: column;
background-color: #000000;
height: 100vh;
max-width: calc(100vh - 100px);
overflow: hidden;
margin-left: auto;
margin-right: auto;
}
.box .row.header {
flex: 0 1 50px;
background-color: #0000ff;
}
.box .row.content {
flex: 1 1 auto;
width: 100%;
background-color: #dc143c;
}
.box .row.footer {
flex: 0 1 40px;
background-color: #00008b;
}
<div class="box">
<div class="row header">
</div>
<div class="row content">
</div>
<div class="row footer">
</div>
</div>
Fiddle: https://jsfiddle.net/901s2kdL/
Content: the biggest square the current width can fit. So width =
height for this one. It should respect the bottom row min-height.
If you want the biggest square, the footer height will be fixed and it will be equal to min-height always (and it should be), so it doesn't matter if you will set it's height to 100% or 50px. max-width of square determining really sizes. If you look at this max-width: calc(100vh - 100px), the - 100px part is the real remaining space including header and footer, so if the header height is set to 50px, the footer height is also 50px.
body {
margin: 0px;
}
.shell {
background-color: black;
}
.header {
height: 50px;
background-color: red;
}
.square {
max-width: calc(100vh - 100px);
margin: 0 auto;
background-color: green;
}
.square:after {
content: "";
display: block;
padding-bottom: 100%;
}
.footer {
height: 50px;
background-color: blue;
}
<div class="shell">
<div class="header"></div>
<div class="square"></div>
<div class="footer"></div>
</div>

How to make a div occupy 100% within another div in Vue

I want to make two div inside other div. But the second(green) div is passing the size of the main(black). I tried to set the height to 100%, but something happens that is going beyond the size of the main box, does anyone have any solutions?
.block {
width: 300px;
height: 200px;
background: black;
}
.box1 {
width: 200px;
height: 50px;
background: red;
vertical-align: top;
margin: auto;
}
.box2 {
width: 200px;
height: 100%;
background: green;
margin: auto
}
<div class="block">
<div class="box1">
</div>
<div class="box2">
</div>
</div>
If you set child's height to 100% then the height of the parent will be inherited. If you are looking for an option where the 2nd box (green) fill the remaining space leftover by 1st box(red)
.block {
width: 300px;
height: 200px;
background: black;
display: flex;
flex-direction: column;
align-items: center;
}
.box1 {
width: 200px;
height: 50px;
background: red;
vertical-align: top;
}
.box2 {
flex: 1;
width: 200px;
background: green;
}
<div class="block">
<div class="box1">
</div>
<div class="box2">
</div>
</div>
I am using Flex and there is no need to use overflow: hidden
You should add the overflow: hidden; to the main black box, just like the below snippet. This will make the overflow clipped.
.block {
width: 300px;
height: 200px;
background: black;
overflow: hidden;
}
.box1 {
width: 200px;
height: 50px;
background: red;
margin: auto;
}
.box2 {
width: 200px;
height: 100%;
background: green;
margin: auto;
}
<div class="block">
<div class="box1">
</div>
<div class="box2">
</div>
</div>
But if you don't want to get rid of the remaining piece of the second box, you can do it with flexbox also. This will not trim the green box but instead, it will resize it to make sure the green box will remain in the parent black box.
.block {
width: 300px;
height: 200px;
background: black;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.box1 {
width: 200px;
height: 50px;
background: red;
}
.box2 {
width: 200px;
height: 100%;
background: green;
}
<div class="block">
<div class="box1">
</div>
<div class="box2">
</div>
</div>
NOTE: In the flexbox version, you also won't need to use margin: auto; in the child boxes, because in the flexbox column direction align-items: center; will take care of child positions with the available attributes it gave to us.

Enable scroll in specified div?

I have following situation. Container c has fixed property. It's always 100% height. Not moving.
Container b has dynamic height.
Container a (body) can't have scrollbar visible at all.
Question: How to force the scrollbar from body to disappear, but the scrollbar in container b to appear? Thanks!
.a {
display: flex;
height: 300px;
}
.b,
.c {
width: 50%;
}
.b {
background: blue;
height: 600px;
overflow-y: scroll;
}
.c {
background: green;
height: 300px;
position: fixed;
right: 0;
}
<div class='a'>
<div class='b'>
</div>
<div class='c'>
</div>
</div>
Credit to SirExotic
Your .b container needs content that exceeds the height of b to activate the scroll bar.
body {
overflow-y: hidden; /* added */
}
.a {
display: flex;
height: 300px;
}
.b,
.c {
width: 50%;
}
.b {
background: blue;
height: 600px;
overflow-y: scroll;
}
.b-content {
min-height: 800px;
}
.c {
background: green;
height: 300px;
position: fixed;
right: 0;
}
<div class='a'>
<div class='b'>
<div class="b-content">
here I am
</div>
</div>
<div class='c'>
</div>
</div>

Scroll list of columns vertically with fixed header but scroll list and header horizontally

jsfiddle: https://jsfiddle.net/jefftg/1chmyppm/
The orange header columns and the white list rows scroll together horizontally, which is desired. However, I want the white list rows to scroll vertically with the orange header fixed at the top. They currently don't. I'm looking for this to work in modern browsers with HTML5/CSS3.
css
.container {
width: 800px;
height: 600px;
overflow-x: auto;
overflow-y: hidden;
}
.header-container {
display: flex;
}
.header-cell {
height: 40px;
min-width: 500px;
background-color: orange;
border: 1px solid red;
}
.data-container {
overflow-y: auto;
overflow-x: hidden;
display: inline-block;
}
.data-row {
overflow-x: hidden;
display: flex;
}
.data-row-cell {
height: 30px;
min-width: 500px;
background-color: white;
border: 1px solid black;
}
html
<div class="header-container">
<div class="header-cell">A</div>
<div class="header-cell">B</div>
<div class="header-cell">C</div>
<div class="header-cell">D</div>
</div>
<div class="data-container">
<div class="data-row">
<div class="data-row-cell">
A1
</div>
<div class="data-row-cell">
B1
</div>
<div class="data-row-cell">
C1
</div>
<div class="data-row-cell">
D1
</div>
</div>
......
</div>
This can be done with pure CSS and you don't need JavaScript.
I've modified your JSFiddle to work the way you are requesting: https://jsfiddle.net/48386nvn/3/
Essentially, .header-container needs to be positioned absolute relative to the .container element:
.container {
width: 800px;
height: 600px;
overflow-x: auto;
overflow-y: hidden;
/* added this: */
position: relative;
}
.header-container {
display: flex;
/* added these: */
position: absolute;
top: 0;
left: 0;
}
The above-mentioned CSS will stick the orange header where you want it and maintain the width you need it to be.
Next, you'll need to make the data scrollable, which is done by doing the following calculation:
height: heightOfParentContainer - heightOfHeaderRow;
The header cell height is 40px (42px when respecting the borders) It also needs a margin-top equal to the height of the header row:
.data-container {
overflow-y: auto;
overflow-x: hidden;
display: inline-block;
/* added these: */
margin-top: 40px;
height: 560px;
}
This should make sure that the header row is not overlapping the data container, and that the height of the data takes up the rest of the space of the overall container.
I was able to get the desired result by simply adding height: 558px to .data-container: jsfiddle.net/jefftg/1chmyppm/2
You don't need to add the overflow to every element, just the elements that need scrolling,
all I did is gave your .data-containera display:block and a certain height so that the overflow-y:auto can work, you can change the height with what you see fits in your page.
this here shows my solution, I hope it helps.
$(".header-container").scroll(function() {
var scrollPercentage = 100 * this.scrollLeft / (this.scrollWidth - this.clientWidth);
$(".data-container").scrollTop(scrollPercentage);
});
.container {
width: 800px;
height: 600px;
}
.header-container {
display: flex;
overflow-x: auto;
}
.header-cell {
height: 40px;
min-width: 500px;
background-color: orange;
border: 1px solid red;
}
.data-container {
overflow-y: auto;
overflow-x: hidden;
display: block;
height: 100px;
}
.data-row {
display: block;
}
.data-row-cell {
height: 50px;
min-width: 500px;
background-color: white;
display: block;
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="header-container">
<div class="header-cell">A</div>
<div class="header-cell">B</div>
<div class="header-cell">C</div>
<div class="header-cell">D</div>
</div>
<div class="data-container">
<div class="data-row">
<div class="data-row-cell">
A1
</div>
<div class="data-row-cell">
B1
</div>
<div class="data-row-cell">
C1
</div>
<div class="data-row-cell">
D1
</div>
</div>
......
</div>

Horizontally centering two stacked divs, when one has a vertical scrollbar

Centering elements horizontally is easy using margin: 0 auto;
However, it doesn't work if there are two elements stacked in a column and one has a scrollbar and the other does not. In that case, the two horizontal centered elements aren't aligned anymore.
Question: Is there any way to align the two elements without using Javascript to adjust the margin of the first one?
JSFIDDLE DEMO
<head>
<style>
body {
margin: 0; height: 100vh;
}
.header {
height: 50px; background: red;
}
.content {
overflow-y: scroll; background: blue;
}
.inner {
background: rgba(255,255,255,.5); max-width: 300px;
margin: 0 auto; min-height: 50px;
}
.content > .inner {
min-height: 300px;
}
</style>
</head>
<body>
<div class="header">
<div class="inner"></div>
</div>
<div class="content">
<div class="inner"></div>
</div>
</body>
The main problem is obviously the centering. So why not circumvent it and use margin-left?
Try this CSS:
.inner { margin-left: calc(50vw - 150px); } /* half viewport width less half element width
(for precise centering) */
body {
margin: 0;
height: 100vh;
}
.header {
height: 50px;
background: red;
}
.content {
background: blue;
overflow-y: scroll;
}
.inner {
background: rgba(255,255,255,.5);
max-width: 300px;
/* margin: 0 auto; <-- remove */
margin-left: calc(50vw - 150px); /* new */
min-height: 50px;
}
.content > .inner {
min-height: 300px;
}
<div class="header">
<div class="inner"></div>
</div>
<div class="content">
<div class="inner"></div>
</div>
Revised Fiddle
Answer from Wes in chat:
This can be solved by adding a scrollbar to the first one, but hiding it from the user.
.header {
height: 50px;
background: red;
overflow-y: scroll;
width: 120%;
margin-left: -10%;
}
JSFIDDLE DEMO
If you're concerned a user could have a scrollbar wider than 10%, increase it width: 300% and margin-left: -100%. If somebody has a scrollbar as wide as the page, he / she can't use the page anyway.