Allow overflow for a inner div only on one axis - html

I have the following where I need the overflow hidden horizontally.
But overflow should be visible vertically.
Having issues where an overflow: hidden on x axis affects y -axis too.
I have tried to specify the axis for over flow as follows but it still hides the y axis.
.container{
.....
overflow-x: hidden;
}
See the screenshots to see what I am trying to achieve.
div.left {
margin-left: 10px;
background:blue;
height:200px;
width:300px;
}
.container{
padding-top: 20px;
margin-top: 10px;
background:black;
height:220px;
width:450px;
overflow: hidden;
}
.container > div {
display: table-cell;
}
.inner {
height: 500px;
background-color: red;
overflow-y: visible;
}
<div class="container">
<div>
<div class="left">
LEFT1
<div class="inner">
INNER
</div>
</div>
</div>
<div>
<div class="left">
LEFT2
</div>
</div>
</div>
Suggestions from from following blogs does not work for this scenario.
https://www.gavsblog.com/blog/only-hide-css-overflow-on-a-single-x-or-y-axis-or-ignore-it
https://css-tricks.com/popping-hidden-overflow/
This is what I have now.
Current
This is what I am trying to achieve.
Expected Result
I can't remove the x-axis overflow cos it would look like this where LEFT2 overflows horizontally which is also incorrect.
Removing overflow
Or is there another way to make overflow hidden on the x axis without the use of overflow:hidden ?

You can try to use grid approach to allow your cells to scroll.
Take a look at Code snippet's comments.
.container {
display: grid; /* make your container grid */
grid-template-columns: 2fr 1fr; /* create grid columns */
column-gap: 10px; /* add gap between columns */
padding: 20px 10px;
margin-top: 10px;
background: black;
height: 220px;
width: 450px;
/* overflow: hidden; */
}
.inner {
height: 500px;
background-color: red;
overflow-y: visible;
}
.container > div {
overflow-x: hidden; /* allow your cell to overflow */
}
div.left {
/*margin-left: 10px;*/
background: blue;
height: 200px;
width: 300px;
}
div.right {
background: green;
height: 300px;
width: 100px;
}
<div class="container">
<div>
<div class="left">
LEFT1
<div class="inner">
INNER
</div>
</div>
</div>
<div>
<div class="left">
LEFT2
</div>
</div>
</div>

Solution is overflow-x: clip:
div.left {
margin-left: 10px;
background:blue;
height:200px;
width:300px;
}
.container{
padding-top: 20px;
margin-top: 10px;
background:black;
height:220px;
width:450px;
overflow-x: clip;
overflow-y: visible;
}
.container > div {
display: table-cell;
}
.inner {
height: 500px;
background-color: red;
}
<div class="container">
<div class="aa">
<div class="left">
LEFT1
<div class="inner">
INNER
</div>
</div>
</div>
<div>
<div class="left">
LEFT2
</div>
</div>
</div>
Note: https://developer.mozilla.org/en-US/docs/Web/CSS/overflow

Related

Visible overflow on X axis, but auto/scroll on axis Y

To keep things neat and short:
https://jsfiddle.net/m53ockLu/
.container {
max-height: 500px;
background: grey;
}
.sidebar {
height: 100vh;
width: 150px;
overflow-x: scroll;
overflow-y: auto;
background: red;
}
.element {
position: relative;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
margin: 5px;
height: 200px;
width: 20px;
background: green;
}
.first {
position: relative;
display: block;
height: 20px;
width: 100px;
background: pink;
}
.second {
display: inline-block;
}
.second-absolute {
position: absolute;
height: 20px;
width: 250px;
background: purple;
}
<div class="container">
<div class="sidebar">
<div class="element">
<div class="first"></div>
<div class="second">
<div class="second-absolute"></div>
</div>
</div>
<div class="element">
</div>
<div class="element">
</div>
<div class="element">
</div>
</div>
</div>
Is it possible to keep the red container scrollable on vertical axis, and at the same time make the purple (.second-absolute) element overflow this red container horizontally? I'm totally out of ideas, I thought that overflow-x & overflow-y should do the trick, but no dice.
Thank you very much for any help.
Is it possible to keep the red container scrollable on vertical axis, and at the same time make the purple (.second-absolute) element overflow this red container horizontally?
No.
I tried Ethan's suggestion and couldn't get the purple box to visibly overflow the scrollbar:
.container {
max-height: 500px;
background: grey;
}
.sidebar {
height: 100vh;
width: 150px;
overflow-y: scroll;
background: red;
}
.element {
position: relative;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
margin: 5px;
height: 200px;
width: 20px;
background: green;
}
.first {
position: relative;
display: block;
height: 20px;
width: 100px;
background: pink;
}
.second {
display: inline-block;
}
.second-absolute {
position: absolute;
height: 20px;
width: 250px;
background: purple;
}
<div class="container">
<div class="sidebar">
<div class="element">
<div class="first"></div>
<div class="second">
<div class="second-absolute"></div>
</div>
</div>
<div class="element">
</div>
<div class="element">
</div>
<div class="element">
</div>
</div>
</div>
I don't think the browser will let you overflow the scrollbar, I even put z-index, explicitly said to visibly overflow, played around with the position property etc.
Consider this example of letting the content dictate the size:
.container {
max-height: 500px;
background: grey;
}
.sidebar {
height: 100vh;
width: max-content;
overflow-y: auto;
background: red;
}
.element {
position: relative;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
margin: 5px;
height: 200px;
background: green;
}
.first {
display: block;
height: 20px;
background: pink;
}
.second {
display: inline-block;
}
.second-absolute {
height: 20px;
width: 250px;
background: purple;
}
<div class="container">
<div class="sidebar">
<div class="element">
<div class="first"></div>
<div class="second">
<div class="second-absolute"></div>
</div>
</div>
<div class="element">
</div>
<div class="element">
</div>
<div class="element">
</div>
</div>
</div>
You made the parent div sidebar have overflow-x: scroll;, overflow-y: auto;. Instead, make each child have its own overflow properties instead of the parent.

child container still go outside of parent 100vh

This is sort of a two in problem.
I have a body with height: 100vh similar to how my example is in the jsFiddle (except in there I put 20vh.
I have a similar structure as this, where the innerRight container can be quite large compared to the rest of the content, and only that conatiner is to obtain it's own scroll bar. I sort of got this working in my main project, but the outer container (similar to how I displayed outer in the example) still expands past the the parents height container main. Be it 100vh, or 20vh it doesn't matter it doesn't stay within with display:flex.
.main {
height: 20vh;
}
.outer {
display: flex;
overflow: hidden;
}
.innerLeft {
height: 200px;
width: 50px;
display: flex;
flex-direction: column;
flex-grow: 1;
background-color: green;
}
.innerRight {
overflow: auto;
height: 500px;
background-color: red;
width: 100%;
}
<div class="main">
<div class="header">
some random text
</div>
<div class="outer">
<div class="innerLeft">
</div>
<div class="innerRight">
</div>
</div>
</div>
Can you please check the below code? Hope it will work for you.
You have to set height:100vh; in .main and set width:calc(100% - 50px); to .innerRight.
Remove height from innerleft and innerright element.
Please refer to this link: https://jsfiddle.net/yudizsolutions/9Lsyzg64/1/
body {
margin: 0;
}
.main {
height: 100vh;
}
.outer {
display: flex;
height: calc(100vh - 19px);
overflow: hidden;
}
.innerLeft {
width: 50px;
background-color: green;
}
.innerRight {
overflow: auto;
background-color: red;
width: calc(100% - 50px);
}
<div class="main">
<div class="header">
some random text
</div>
<div class="outer">
<div class="innerLeft">
</div>
<div class="innerRight">
</div>
</div>
</div>
You need to set height to outer class.
.main {
height: 20vh;
}
.outer {
display: flex;
height: 200px;
overflow:hidden;
}
.innerLeft {
width: 50px;
display: flex;
flex-direction: column;
flex-grow: 1;
background-color: green;
}
.innerRight {
overflow: auto;
height: 500px;
background-color: red;
width:100%;
}
<div class="main">
<div class="header">
some random text
</div>
<div class="outer">
<div class="innerLeft">
</div>
<div class="innerRight">
</div>
</div>
</div>

css let element width auto grow while parent width auto

I have a html structure like this and some basic style
.container {
display: block;
width: auto;
/* this is must */
height: auto;
/* this is must */
max-width: 300px;
}
.container .row {
display: flex;
width: 100%;
height: auto;
}
.container .row .left {
display: inline-block;
width: 100px;
height: auto;
}
.container .row .right {
display: inline-block;
width: auto;
height: auto;
}
<div class="container">
<div class="row">
<div class="left"></div>
<div class="right"></div>
</div>
<div class="row">
<div class="left"></div>
<div class="right"></div>
</div>
<div class="row">
<div class="left"></div>
<div class="right"></div>
</div>
</div>
The style may not working, I only pasted the basic part of it.
What I want to achieve is, the parent element has a max-width, it contains multiple rows, each row has two elements, 'left' and 'right'. I give a fixed width to 'left' element, and a min-width/max-width to 'right' element. I would like the width of the right element auto grow as the content grow until the max-width, but if the content is short, the right element shall also shrink.
I tried table and flex box, but no luck. Thanks for any help
The problem is because you have to specify the max-width to the .right class.
1) The overall container's max-width:300px and left one's width: is 100px, so the remaining 200px; you can give it to right row.
2) Have added background for better understanding.
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<style>
.container {
display: block;
width: auto; /* this is must */
height: auto; /* this is must */
max-width: 300px;
}
.container .row{
display: flex;
width: 100%;
height: auto;
background-color:Red;
}
.container .row .left{
display: inline-block;
width: 100px;
background-color:yellow;
}
.container .row .right{
display: inline-block;
height: auto;
background-color:green;
max-width: 200px;
overflow:hidden;
}
</style>
<body>
<div class="container">
<div class="row">
<div class="left">qweqweqwe</div>
<div class="right">qweqweqwew<p>afdllssssssssdddddddddssssssssss</p><p>asdasdasdadsas</p></div>
</div>
<div class="row">
<div class="left">qweqweqwe</div>
<div class="right">qweqweqwe</div>
</div>
<div class="row">
<div class="left">qweqweqw</div>
<div class="right">qweqweqweqwe</div>
</div>
</div>
</body>
</html>
Find the codepen sample here and check it with your requirement. Also, let me know if there is something that you want to get from.
.container .row{
display: flex;
width: 100%;
height: auto;
}
.container .row .left{
display: inline-block;
width: 100px;
height: auto;
}
.container .row .right{
display: inline-block;
width: auto;
height: auto;
max-width: 150px;
overflow: hidden;
}
Add display: flex to your .row class and set min-width: 100px to .right - see a working jsfiddle here: https://jsfiddle.net/o3o9j4za/1/
<div class="container">
<div class="row">
<div class="left">1234</div>
<div class="right">4312</div>
</div>
<div class="row">
<div class="left">1235</div>
<div class="right">qweqwereqwr</div>
</div>
<div class="row">
<div class="left">5342</div>
<div class="right">3g43g3g3g</div>
</div>
.container {
display: block;
width: auto; /* this is must */
height: auto; /* this is must */
max-width: 300px;
}
.container .row{
width: 100%;
height: auto;
display:flex;
}
.container .row .left{
display: inline-block;
height: auto;
width: 100px;
background-color:#ff0;
}
.container .row .right{
display: inline-block;
width: auto;
min-width: 100px;
height: auto;
background-color:#f0f;
}
Note, that your flex container (.row) is affected by the max-width of .container.
(Edit: misread a bit - should be like you want it now?)
How about this flexbox solution? I think it comes closest to what you are looking for:
<div class="container">
<div class="row">
<div class="left">test left</div>
<div class="right">test right</div>
</div>
<div class="row">
<div class="left">test left</div>
<div class="right">test right</div>
</div>
<div class="row">
<div class="left">test left</div>
<div class="right">test right</div>
</div>
</div>
.container {
padding: 2px;
border: 1px solid green;
max-width: 300px;
}
.row {
display: flex;
padding: 2px;
border: 1px solid red;
max-width: 300px;
}
.left {
padding: 2px;
border: 1px solid blue;
width: 100px;
}
.right {
padding: 2px;
border: 1px solid purple;
width: 180px;
}
And the fiddle:
https://jsfiddle.net/xr7ebmsz/
I guess you can try this one for your class "right"
.right{
width:calc(100% - 100px);
}

css how to make columns auto fill background color to height 100%

I have the following code:
#left {
float: left;
width: 180px;
background-color: #ff0000;
}
#right {
overflow: hidden;
background-color: #00FF00;
}
<div>
<div id="left">
left
</div>
<div id="right">
right<br/> down
</div>
</div>
What I am trying to achieve is to make the left column's background-color to fill the whole div. This should be the case regardless of the height of the #right column.
so far I have tried/added
display: flex;
height: 100%
flex 1;
To the #left style but it is not working.
This has to be a CSS only solution.
You can use flexbox here. Demo:
.container {
/* become a flex-container */
/* flex-items will be stretched vertically by default */
display: flex;
}
#left {
width: 180px;
background-color: #ff0000;
}
#right {
/* occupy remaining width */
flex: 1;
background-color: #00FF00;
}
<div class="container">
<div id="left">
left
</div>
<div id="right">
right
<br/> down
</div>
</div>
Also you can use CSS Grid layout here. Demo:
.container {
/* become a grid-container */
display: -ms-grid;
display: grid;
/* first column should occupy 180px and second should occupy remaining width */
-ms-grid-columns: 180px 1fr;
grid-template-columns: 180px 1fr;
}
#left {
background-color: #ff0000;
}
#right {
background-color: #00FF00;
/* specify column for IE/Edge explicitly */
-ms-grid-column: 2;
}
<div class="container">
<div id="left">
left
</div>
<div id="right">
right
<br/> down
</div>
</div>
Need to understand why #left doesn't takes height of 100% and that's because you have used float:left property in #left. So whenever float left is used on an element it by default changes it display to inline-block and that's the reason that you have to change display of your parent div to overcome this.
Here is below using flex,
div{
display:flex;
}
div #left {
width: 180px;
background-color: #ff0000;
}
div #right {
flex:1;
overflow: hidden;
background-color: #00FF00;
}
<div>
<div id="left">
left
</div>
<div id="right">
right<br/> down
</div>
</div>
Read this to understand how float works.
.main-table {
display: table;
}
#left {
display: table-cell;
float: none;
width: 180px;
background-color: #ff0000;
}
#right {
display: table-cell;
overflow: hidden;
background-color: #00FF00;
}
<div class="main-table">
<div id="left">
left
</div>
<div id="right">
right<br/> down
</div>
</div>
Something like table may help you in this case!!

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>