Keep vertical scrollbar in a fixed position independent of horizontal scroll - javascript

I currently have a grid set up that looks something like this:
<div class="grid-container">
<div class="headers"> <!-- ... --></div>
<div class="row-container">
<div class="row"> <!-- ... --></div>
<!-- ... -->
</div>
</div>
Essentially what I'd like to do is place an overflow-x on the entire grid-container (so that scrolling horizontally will scroll both the headers and the rows together), but just place an overflow-y: overlay on the row-container (so that scrolling down will only scroll through the rows and keep the grid headers in a fixed position.
I was able to do that and it looks okay, however, the vertical scrollbar on the row-container is at the far right of the row-container. I'd like it to be visible and in a fixed position (similar to how it would look if you were to place an overflow-y on the entire grid-container except without affecting the headers).
Sorry I know I probably explained this poorly, but here's a JSFiddle that should hopefully illustrate the problem I'm having: https://jsfiddle.net/4xwd5yzp/
Notice in that fiddle, you can only see the vertical scrollbar when you scroll to the end of the row-container.
Thank you in advance for any help. Ideally, I'd prefer a solution using just HTML + CSS, but I'm also open to use vanilla JS + jQuery if absolutely necessary.
EDIT: Here is an example of how it currently works (not ideal):
And here is a photo of how I want it to look:

You were very close, if you take the overflow-y style off of .row-container and add it to .grid-container and also add position: sticky; and background: white; to .headers then I believe it'll work how you want it to.

Update the width in % rather than px.
`
.grid-container {
border: 1px solid black;
height: 200px;
width: 99%x;
white-space: nowrap;
overflow-x: auto;
overflow-y: hidden;
}
.row-container {
height: 150px;
width: 99%x;
overflow-y: overlay;
}
.grid-cell {
display: inline-block;
width: 250px;
}
.headers {
border-bottom: 1px solid black;
height: 50px;
width: 99%;
}
.row {
border-bottom: 1px solid lightgray;
height: 30px;
width: 99%;
}
`

Related

In a html css angular table that is scrollable through overflow-x, is there a way to fix the right-most column?

In a html css angular table that is scrollable through overflow-x, is there a way to fix the right-most column so that when i scroll from left to right, that column stays there?
I tried the sticky property, as well as creating two tables right next to eachother (which does not accomplish the task successfully. I am thinking that i should overlay two tables on top of eachother but i am not sure how i should go about this.
position: sticky appears to work fine on chrome and firefox:
div {
width: 100%;
overflow: hidden;
overflow-x: scroll;
}
table, th, td {
border: 1px solid black;
background-color: white;
}
table {
width: 1000px;
}
.sticky-col {
width: 40px;
position: sticky;
right: 0;
}
<div>
<table>
<tr><th>1</th><th>2</th><th class="sticky-col">3</th></tr>
<tr><td>1,1</td><td>1,2</td><td class="sticky-col">1,3</td></tr>
<tr><td>2,1</td><td>2,2</td><td class="sticky-col">2,3</td></tr>
<tr><td>3,1</td><td>3,2</td><td class="sticky-col">3,3</td></tr>
</table>
</div>

make a div fit into whitespace if possible, else grow in size

my question is rather complicated.
In my layout i have a left column and a right column. For example 30% and 70% width. below them there is another item, now theres the challenge:
if my 30% column is higher than the 70% column the "challengeblock" should fill on the right side.
if the right side is the higher one the "challengeblock" should be on the bottom with 100% width.
Here I made an example:
https://jsfiddle.net/by6tkg7L/
The green one should fit on the right in this code.
I tried it with
flex-grow
in this case, but also had a try with grid (not to experienced there so seems like I need to read some more first)
I´m also open for masonary layouts like with isotope, but found no way so far to make it fill OR make it grow depending on the rest.
I would ofcourse prefer a CSS-only way and would like to avoid calculating with JS.
Tahnks in advance
Css only solution. Working fiddle: https://jsfiddle.net/by6tkg7L/1/
To be able to see it working you have to change height of the blue block (class .right_top).
I only modified the css, i used block and inline-block on the child elements (with float: left) and i've set flex only on the question element setting a min-width and a max-width instead of a static width.
CSS:
.wrapper{
display: block;
width: 100%;
flex-wrap: wrap;
flex-direction: row;
}
.left{
background-color: red;
height: 500px;
width: 30%;
display:inline-block;
float:left;
}
.right_top{
background-color: blue;
height: 500px;
width: 70%;
display:inline-block;
float:left;
}
.question{
min-width: 70%;
width: auto;
max-width: 100%;
background-color: green;
height: 300px;
display:flex;
}
HTML:
<div class="wrapper">
<div class="left">
</div>
<div class="right_top">
</div>
<div class="question">
</div>
</div>

Partially fixed header, fixed footer, and a variable width content that is scrollable in the X and Y directions as content grows

There are lots of fixed footer/header variable width content posts but none seem to work for my specific use case.
The easiest way to describe what I want is a google doc's style interface where the header and footer are fixed and the content is X/Y scrollable but was part of the header scrolls away when you start scrolling down
https://jsfiddle.net/zve0mb5m/
HTML, body {
width: 100%;
height: 100%;
margin: 0px;
padding: 0px;
}
div {
padding: 10px;
}
.header {
background: LightCoral;
border: 10px solid IndianRed;
}
.fixed-header {
position: sticky;
top: 0px;
background: Gold;
border: 10px solid GoldenRod;
}
.content {
overflow-y: scroll;
overflow-x: scroll;
height: 100%;
background: YellowGreen;
border: 10px solid OliveDrab;
}
.fixed-footer{
position: fixed;
bottom: 0px;
background: LightSteelBlue;
border: 10px solid SteelBlue;
width: 100%;
}
<div class="header">
<h1>Non fixed header content</h1>
</div>
<div class="fixed-header">
Fixed header content
</div>
<div class="content">
Some content that will overflow horizontally aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
</div>
<div class="fixed-footer">
Fixed footer content
</div>
The above fiddle is what I have so far, in a working solution the border for the green content section would appear just above the blue footer which would allow the horizontal scroll bar to be present.
Also, when scrolling the content section goes underneath the fixed header which isn't ideal. I want the content section to be fully visible at all times, and grow as we scroll. Possible with CSS? Do I need some JS in here?
You can wrap the fixed items in a container div and use flexbox to lay them out the way you want: http://jsfiddle.net/38m5d13r/

How to define the width of a HTML element dynamically

I have a single container div with two child div's. The container div is 100% width. The child div's are left floated. The left div's width is not set because it's contents must decide it's width. The right div's width must be 100% minus the width of the left div.
HTML:
<div class="container">
<div class="message-name"><p>User :</p></div>
<div class="message-msg"><p>Some message</p></div>
</div>
<div class="container">
<div class="message-name"><p>User : </p></div>
<div class="message-msg"><p>Some really long message that breaks to new line because it is too long to stay on this line. mmmm mmmmmmmmmmmmm mmmmmmmmmmmmm mmmmmmmmmmm mmmmmmmmmm mmmmmmmmm mmmmmmmmm mmmmmmmmmm mmmmmmmmmm mmmmmmmmm mmmmmmmm</p></div>
</div>
CSS:
*{margin:0;pading:0;}
.container{
width:100%;
min-height: 20px;
overflow: auto;
}
.message-name{
height: 20px;
text-align: left;
float: left;
border: 1px solid red;
}
.message-msg{
border: 1px solid red;
min-height: 20px;
float: left;
}
This is my attempt at using JQuery to dynamically set the width of the right div when it is added to the page dynamically:
$(document).ready( function(){
var nameWidth = $(".message-name").last().width();
alert(nameWidth);
$(".message-msg").last().css("width","100%").width($(".message-msg").last() - nameWidth);
});
But it doesn't change anything.
How can I get the width of the left div and then subtract that from the width of the right div to ensure the right div does not break to a new line?
Here is a JSFiddle of my attempt.
Use flexbox, it's support is wide enough for most reasonable purposes.
No scripting required, much more FLEXible!
* {
margin:0;
padding:0;
}
.container {
width:100%;
min-height: 20px;
overflow: auto;
display: flex;
flex-direction: row;
}
.message-name {
height: 20px;
text-align: left;
border: 1px solid red;
flex-shrink: 0;
}
.message-msg {
border: 1px solid red;
min-height: 20px;
flex-grow: 1;
flex-shrink: 1;
}
<div class="container">
<div class="message-name"><p>User :</p></div>
<div class="message-msg"><p>Some message</p></div>
</div>
<div class="container">
<div class="message-name"><p>User : </p></div>
<div class="message-msg"><p>Some really long message that breaks to new line because it is too long to stay on this line. mmmm mmmmmmmmmmmmm mmmmmmmmmmmmm mmmmmmmmmmm mmmmmmmmmm mmmmmmmmm mmmmmmmmm mmmmmmmmmm mmmmmmmmmm mmmmmmmmm mmmmmmmm</p></div>
</div>
Also on JSFiddle
A more efficient way to use flexbox is to just declare the .message-msg block to be flex: https://jsfiddle.net/84vocLbk/. It'll be situated horizontally next to the .message-name and stretch the available width.
CSS:
.message-msg {
border: 1px solid red;
min-height: 20px;
display: flex;
}
Please try this
$(".message-msg").last().width($(".message-msg").last().width() - nameWidth);
Border 2px for each div is present. If you want to place it to the left then try this
$(".message-msg").last().width($(".message-msg").last().width()-2 - nameWidth-2);
DEMO without removing border
DEMO after removing the border
Add this
$(".message-msg").last().css("width","100%").width($(".message-msg").last().width() - nameWidth);
In thaat line you're setting the width to 100% then changing that width to 100% minus the variable nameWidth You have to get width of last div to do calculations
You can achieve this with CSS.
fiddle: https://jsfiddle.net/zof15z6c/7/
This works by setting the overflow of the second div to hidden or auto. if your content is just a text I suggest setting it to hidden since the text would just wrap around.
Changes to the css
.message-msg{
border: 1px solid red;
min-height: 20px;
overflow:hidden;
}
Advantages:
Works on most browsers (tested in IE7)
The browser takes care of window resizes
Cleaner code
Disadvantages
Overflow should either be hidden or auto. This will not be an issue for you since you just have text.

CSS top div to adjust height automatically

There're 2 divs - top and bottom.
The bottom should serve as a 'buttons pane', so visible and 'pinned' to bottom border at all times. root div is a Kendo UI Window div (see jsbin fiddle)
The problem is that the scrollbar is not being shown ONLY for the top div, but for 'buttons pane' as well. In the given jsbin resize down the window vertically, so the scrollbar appears:
http://jsbin.com/UrasoKi/3/edit
<style scoped>
#top{
min-height: 500px;
width: 100%;
background-color: blue
}
#bottom{
height: 50px;
width: 100%;
background-color: green;
position: absolute;
bottom: 0px;
/*kendo specific margin indentation, ignore*/
margin: 0 0 0 -9px;
}
</style>
<div id="w">
<div id="top">TOP PANE</div>
<div id="bottom">BOTTOM PANE</div>
</div>
I would like to achieve clear bottom div positioning with css. Scrollbar should appear for TOP panel ONLY.
Elements MUST BE positioned INSIDE <div id='w'/> in fiddle (because of telerik kendo window resize handles) AND BE RESIZABLE, so any extra volume would be given to the top pane. But extra divs could be added into it (into div id="w")
I've been trying to play around for hours, something is missing.
I would tweak as follows to provide the sort of functionality you want:
<body>
<style scoped>
#top{
height: 100%;
width: 100%;
}
#bottom{
height: 50px;
width: 100%;
background-color: green;
position: absolute;
bottom: 0px;
/*kendo specific margin indentation, ignore*/
margin: 0 0 0 -9px;
}
#inner {
overflow-y:scroll;
height: 100%;
background-color: blue
}
</style>
<div id="w">
<div id="top"><div id="inner">TOP PANE</div></div> <div id="bottom">BOTTOM PANE</div>
</div>
<script>
$(document).ready(function() {
$('#w').kendoWindow({
width: '450px'
});
$('.k-window-content').css({'overflow':'hidden', scrollable: false })
});
</script>
</body>
The tweaks include fixing the size of the Kendo Window and adding an inner div with fixed height and overflow-y scrolling for the top panel.
I hope this helps...
The attribute min-height: 500px; is causing the window to show a scrollbar. You would want to put the two divs in another div with a fixed min-height and then give the two divs a fixed min-height
Edit:
Edited your fiddle, see if that is what you need.
http://jsbin.com/efOgoVE/10/edit

Categories

Resources