HTML - Sticky position partially working for table - javascript

I want to build a first column sticky with css position:sticky and left:0.
While I have a header and a table, with overflow-x: scroll set.
However, when I start to scroll to right, the first column for the table body is partially working and starting to move once it passed the width of its parent. For the table header it doesn't have such problem.
Please may I have your to provide some insights here
Here is my codepen for reference. Thanks a lot!!
https://codepen.io/jackforfun/pen/yLPwYoz

Add to your .row-container the two css properties below:
display: flex;
flex-wrap: wrap;
.cell {
padding: 25px;
flex: 0 0 100px;
border: 1px solid grey;
}
.cell-1 {
padding: 25px;
flex: 0 0 100px;
border: 1px solid grey;
background-color: red;
position: sticky;
left: 0;
}
.header {
display: flex;
background-color: orange;
width: 500px;
overflow-x: scroll;
}
.row-container {
display: flex;
flex-wrap: wrap;
width: 500px;
overflow-x: scroll;
}
.row {
display: flex;
background-color: green;
}
<div>
<div class="header">
<div class="cell-1">First</div>
<div class="cell">Header</div>
<div class="cell">Header</div>
<div class="cell">Header</div>
<div class="cell">Header</div>
<div class="cell">Header</div>
<div class="cell">Header</div>
</div>
<div class="body">
<div class="row-container">
<div class="row">
<div class="cell-1">Content</div>
<div class="cell">Content</div>
<div class="cell">Content</div>
<div class="cell">Content</div>
<div class="cell">Content</div>
<div class="cell">Content</div>
</div>
<div class="row">
<div class="cell-1">Content</div>
<div class="cell">Content</div>
<div class="cell">Content</div>
<div class="cell">Content</div>
<div class="cell">Content</div>
<div class="cell">Content</div>
</div>
</div>
</div>
</div>
UPDATE: 2nd Question
I cleaned up you code a little bit. You mixed inline styles with css styles. But the main solution for your second question was to assign a width for cell-1 and remove the flex 0 0 100properties for the cell-1.
.cell-1 {
border: 1px solid grey;
background-color: red;
position: sticky;
left: 0;
width:200px;
}
.cell {
padding: 25px;
height: 50px;
flex: 0 0 100px;
border: 1px solid grey;
}
.cell-1 {
border: 1px solid grey;
background-color: red;
position: sticky;
left: 0;
width:200px;
}
.row-container {
overflow-x: scroll;
flex-wrap:wrap;
display:flex;
}
.row {
display: flex;
background-color: green;
}
.grid {
width: 350px;
}
<div class="grid">
<div class="row-container">
<div class="row">
<div class="cell-1 cell" >
First Column
</div>
<div class="cell" >
Column
</div>
<div class="cell" >
Column
</div>
<div class="cell">
Column
</div>
<div class="cell" >
Column
</div>
<div class="cell">
Column
</div>
<div class="cell" >
Column
</div>
</div>
<div class="row">
<div class="cell cell-1">
First Column
</div>
<div class="cell">
Column
</div>
<div class="cell" >
Column
</div>
<div class="cell" >
Column
</div>
<div class="cell" >
Column
</div>
<div class="cell" >
Column
</div>
<div class="cell" >
Column
</div>
</div>
</div>
</div>

Lowrey answer is perfectly working for above question. Thank you for that.
However, I got another similar problem when even adding the flex-wrap
cannot be resolved.
There is a table with two rows, and the first column stick to the left.
While it is scrolling horizontally, the first column was sticked initially. After a while, the first column cannot stick anymore and start to move.
The situation is a bit similar to the original question.
Thank you for advance for checking this.
.cell {
padding: 25px;
height: 50px;
flex: 0 0 100px;
border: 1px solid grey;
}
.cell-1 {
padding: 25px;
flex: 0 0 100px;
border: 1px solid grey;
background-color: red;
position: sticky;
left: 0;
}
.row-container {
overflow-x: scroll;
flex-wrap:wrap;
display:flex;
}
.row {
display: flex;
background-color: green;
}
.grid {
width: 350px;
}
<div class="grid">
<div class="row-container">
<div class="row">
<div class="cell-1" style="flex: 1 0 150px; ">
First Column
</div>
<div class="cell" style="flex: 1 0 100px; ">
Column
</div>
<div class="cell" style="flex: 1 0 100px; ">
Column
</div>
<div class="cell" style="flex: 1 0 100px; ">
Column
</div>
<div class="cell" style="flex: 1 0 100px; ">
Column
</div>
<div class="cell" style="flex: 1 0 100px; ">
Column
</div>
<div class="cell" style="flex: 1 0 100px; ">
Column
</div>
</div>
<div class="row">
<div class="cell-1" style="flex: 1 0 150px; ">
First Column
</div>
<div class="cell" style="flex: 1 0 100px; ">
Column
</div>
<div class="cell" style="flex: 1 0 100px; ">
Column
</div>
<div class="cell" style="flex: 1 0 100px; ">
Column
</div>
<div class="cell" style="flex: 1 0 100px; ">
Column
</div>
<div class="cell" style="flex: 1 0 100px; ">
Column
</div>
<div class="cell" style="flex: 1 0 100px; ">
Column
</div>
</div>
</div>
https://codepen.io/jackforfun/pen/abVMyMd

I am really appreciate what Lowrey help here. Thank you so much.
The provide solution for 2nd question is really helpful and able to resolve this question.
However, when I extend the width of the cells and it seems the problem happened again.
https://codepen.io/jackforfun/pen/YzEgvRj
.long-cell { flex: 0 0 300px;}
.cell {
padding: 25px;
height: 50px;
flex: 0 0 100px;
border: 1px solid grey;
}
.cell-1 {
border: 1px solid grey;
background-color: red;
position: sticky;
left: 0;
width:200px;
}
.long-cell {
flex: 0 0 300px;
}
.row-container {
overflow-x: scroll;
flex-wrap:wrap;
display:flex;
}
.row {
display: flex;
background-color: green;
}
.grid {
width: 350px;
}
<div class="grid">
<div class="row-container">
<div class="row">
<div class="cell-1 cell" >
First Column
</div>
<div class="cell" >
Column
</div>
<div class="cell" >
Column
</div>
<div class="cell">
Column
</div>
<div class="cell long-cell" >
Column
</div>
<div class="cell">
Column
</div>
<div class="cell " >
Column
</div>
</div>
<div class="row">
<div class="cell cell-1">
First Column
</div>
<div class="cell">
Column
</div>
<div class="cell" >
Column
</div>
<div class="cell" >
Column
</div>
<div class="cell long-cell" >
Column
</div>
<div class="cell" >
Column
</div>
<div class="cell" >
Column
</div>
</div>
</div>
</div>

Related

How to Let Float Items Split the Blank Area in Average?

Please run this demo:
.app {
background:pink;
width: 90vw;
overflow: hidden;
}
.app__item {
background: lightblue;
width: 200px;
float :left;
margin:5px;
height: 40px;
}
.app__item:last-child {
float: right;
}
.app__item--size2 {
height: 90px;
}
<div class="app">
<div class="app__item app__item--size2">1</div>
<div class="app__item">2</div>
<div class="app__item">3</div>
<div class="app__item">4</div>
<div class="app__item">5</div>
<div class="app__item">6</div>
<div class="app__item">7</div>
<div class="app__item">8</div>
<div class="app__item">9</div>
<div class="app__item">10</div>
<div class="app__item">
<button>search</button>
</div>
</div>
Please notice the red color text which is what I want:
How to Let Float Items Split the Blank Area in Average?
This gif point out what I want and also the reason why I am using float layout.
If using flex, the result would be
.app {
background:pink;
width: 80vw;
display: flex;
flex-flow: row wrap;
}
.app__item,
.app__item_wrapper {
margin:5px;
width: 200px;
flex: 0 0 auto;
}
.app__item {
background: lightblue;
height: 40px;
}
.app__item_wrapper {
display: flex;
flex-flow: column;
justify-content: space-between;
}
.app__item--size2 {
height: 90px;
}
.app__item--inner {
margin:0;
flex: 0 0 auto;
}
<div class="app">
<div class="app__item app__item--size2">1</div>
<div class=" app__item_wrapper app__item--size2">
<div class="app__item app__item--inner">2</div>
<div class="app__item app__item--inner">3</div>
</div>
<div class=" app__item_wrapper app__item--size2">
<div class="app__item app__item--inner">4</div>
<div class="app__item app__item--inner">5</div>
</div>
<div class="app__item">6</div>
<div class="app__item">7</div>
<div class="app__item">8</div>
<div class="app__item">
<button>search</button>
</div>
</div>
And the con is that it won't work well when viewport is changing. See this:
and this is the con:
If I understand correctly, you're wanting the cells to the right of "cell 1" to stretch-to-fill the reaming horizontal space of the enclosing div (with pink background).
You could use CSS Grid to achieve this as shown below:
.app {
background:pink;
width: 90vw;
padding:5px;
display:grid;
/* Cause first column with to be 200px, remaining two columns
to scale to fit remaining width */
grid-template-columns: 200px repeat(2, 1fr);
/* Set spacing between cells */
grid-gap:10px;
}
.app__item {
background: lightblue;
width: 100%;
height: 40px;
}
.app__item--size2 {
/* Cause top left cell to occupy two rows */
grid-row: 1 / 3;
height:100%;
}
<div class="app">
<div class="app__item app__item--size2">1</div>
<div class="app__item">2</div>
<div class="app__item">3</div>
<div class="app__item">4</div>
<div class="app__item">5</div>
<div class="app__item">6</div>
<div class="app__item">7</div>
<div class="app__item">8</div>
<div class="app__item">9</div>
<div class="app__item">10</div>
<div class="app__item">
<button>search</button>
</div>
</div>
Thank #Dacre Denny for giving me inspiration. Finally, I got it.
.app {
background:pink;
width: 90vw;
padding:5px;
display:grid;
grid-template-columns: repeat(auto-fit,200px);
justify-content:space-evenly;
grid-gap: 5px;
}
.app__item {
background: lightblue;
width: 200px;
height: 40px;
}
.app__item--size2 {
/* Cause top left cell to occupy two rows */
grid-row: 1 / 3;
height:100%;
}
.app__item:last-child {
grid-column-end: -1
}
<div class="app">
<div class="app__item app__item--size2">1</div>
<div class="app__item">2</div>
<div class="app__item">3</div>
<div class="app__item">4</div>
<div class="app__item">5</div>
<div class="app__item">6</div>
<div class="app__item">7</div>
<div class="app__item">8</div>
<div class="app__item">9</div>
<div class="app__item">10</div>
<div class="app__item">
<button>search</button>
</div>
</div>
See this gif when viewport is changing.

Vertical scrolling but remove scrollbar

This has been asked several times across the internet; however, I can't get a solution that works for me. I need to maintain the ability to have vertical scrolling but hide the scrollbar from view at all times in the y direction.
I need my #content-main div to scroll independently from every other div. This works as is; however, I have a scrollbar I need to get rid of but I don't know how or why it is so difficult to do.
My code is set up like so:
<body>
<div id="ipad">
<div id="sidebar-main">
<div id="logo-main">Title</div>
<div class="sidebar-option"></div>
<div class="sidebar-option"></div>
<div class="sidebar-option"></div>
<div class="sidebar-option"></div>
<div class="sidebar-option"></div>
<div class="sidebar-option"></div>
<div class="sidebar-option"></div>
<div class="sidebar-option"></div>
</div>
<div id="content-main">
<div id="search-main">
<div id="category-search">
<i id="hamburger-icon" class="fa fa-bars"></i>
<input type="text" placeholder="auto loans" />
<i id="search-icon" class="fa fa-search"></i>
</div>
</div>
<div id="page-content">
<img id="home-img" src="home-page.png" /> /* temp */
</div>
</div>
</div>
</body>
And the CSS relevant for what I'm trying to do:
* {
font-family: 'Open Sans', sans-serif;
margin: 0;
}
html, body {
margin: 10px;
padding: 0;
background: #ccc;
overflow: hidden;
}
#ipad {
padding: 0;
margin: 0;
width: 768px;
height: 1024px;
background: #fff;
overflow: hidden;
}
#content-main {
width: 600px;
height: 100%;
float: right;
overflow: auto;
}
I've seen this "solution" but it does not work for me: http://jsfiddle.net/5GCsJ/954/
And I've seen this but these did not work when applied to my #content-main div: http://blogs.msdn.com/b/kurlak/archive/2013/11/03/hiding-vertical-scrollbars-with-pure-css-in-chrome-ie-6-firefox-opera-and-safari.aspx
Any help would be greatly appreciated.
I have given CSS for two div separately #content-main div to scroll independently from every other div. And Should Close the DIV of #ipad div before start of #content-main div. here is the code of what you want.
<body>
<div id="ipad">
<div id="sidebar-main">
<div id="logo-main">Title</div>
<div class="sidebar-option"></div>
<div class="sidebar-option"></div>
<div class="sidebar-option"></div>
<div class="sidebar-option"></div>
<div class="sidebar-option"></div>
<div class="sidebar-option"></div>
<div class="sidebar-option"></div>
<div class="sidebar-option"></div>
</div>
</div>
<div id="content-main">
<div id="search-main">
<div id="category-search">
<i id="hamburger-icon" class="fa fa-bars"></i>
<input type="text" placeholder="auto loans" />
<i id="search-icon" class="fa fa-search"></i>
</div>
</div>
<div id="page-content">
<img id="home-img" src="home-page.png" /> /* temp */
</div>
</div>
<style>
*{margin:0;}
#ipad{
height: 300px;
width: 100%;
border: 1px solid green;
overflow: hidden;
}
#sidebar-main{
width: 100%;
height: 99%;
border: 1px solid blue;
overflow: auto;
padding-right: 15px;
}
#content-main{
width: 100%;
height: 100px;
border: 1px solid blue;
overflow: auto;
padding-right: 15px;
}
html, body{
height: 99%;
border: 1px solid red;
overflow:hidden;
}
</style>

Show floated div with percentage width and different pattern

I am not very good with CSS, so I am posting my problem here hoping for a solution:
What I need is following:
I need an HTML row/div/line that shows a date and after the date it shows a bar which will be a percentage of the remaining screen width.
Like so:
2015-11-17 ---------------------(50%)
2015-11-18 ------------------------------------------- (80%)
2015-11-19 ==================================================== (100%)
If you will please consider in the dashes as a proper bar (like 10px height for e.g.). You might notice that 50% and 80% have ---- while 100% has ====.
This is because for any percentage less than 100 I want the bar to be a mixed color like blue and white combo. For the 100% it will be a solid blue color bar.
I am trying to achieve this using HTML/CSS only, but I find my expertise to be lacking.
So far, I have following HTML/CSS:
<div style="padding-top: 10px;padding-bottom:10px; width:100%">
<div style='float:left'><strong>Date </strong>{{Today.date}}</div>
<div style='float:left;background-color:red;width:100%'></div>
</div>
The above code does not even show the second div with red background :(
Any pointers in helping me solve this is very much appreciated!
Flexbox could help here depending on your browser support requirements.
.wrap {
width: 80%;
margin: 1rem auto;
font-size: 24px;
display: flex;
align-items: center;
border: 1px solid grey;
}
.date {
padding: 0 1em;
}
.bar {
height: 10px;
background: #f00;
}
.bar-50 {
flex: .5;
}
.bar-80 {
flex: .8;
}
.bar-100 {
flex: 1;
}
<div class="wrap">
<div class="date">2015-11-17</div>
<div class="bar bar-50"></div>
</div>
<div class="wrap">
<div class="date">2015-11-18</div>
<div class="bar bar-80"></div>
</div>
<div class="wrap">
<div class="date">2015-11-19</div>
<div class="bar bar-100"></div>
</div>
Sneaky version with pseudo-element instead of extra HTML
.bar {
width: 80%;
margin: 1rem auto;
font-size: 24px;
display: flex;
align-items: center;
border: 1px solid grey;
}
.date {
padding: 0 1em;
}
.bar::after {
content: '';
height: 10px;
background: #f00;
}
.bar-50:after {
flex: .5;
}
.bar-80:after {
flex: .8;
}
.bar-100:after {
flex: 1;
}
<div class="bar bar-50">
<div class="date">2015-11-17</div>
</div>
<div class="bar bar-80">
<div class="date">2015-11-18</div>
</div>
<div class="bar bar-100">
<div class="date">2015-11-19</div>
</div>
Perhaps more semantically, use a progress element and a label.
Progess Element # MDN
div {
margin: 10px;
}
<div>
<label for="alpha">2015-11-17</label>
<progress id="alpha" value="50" max="100">50 %</progress>
</div>
<div>
<label for="beta">2015-11-18</label>
<progress id="beta" value="70" max="100">70 %</progress>
</div>
<div>
<label for="gamma">2015-11-19</label>
<progress id="gamma" value="100" max="100">70 %</progress>
</div>
You can try this
<div style="padding-top: 10px;padding-bottom:10px; width:100%;position: relative;">
<div style="float: left;width: 50%;display: inline-block;"><strong>Date </strong>{{Today.date}}</div>
<div style="float:left;width: 50%;height: 10px;display: inline-block;">
<div class="progress" style="background-color:red;width: 100%;height: 100%;">
</div></div>
</div>

Auto fit dynamic div block

<div class="main">
<div class="test" style="width:40px;height:100px"><div>
<div class="test" style="width:20px;height:150px;"><div>
<div class="test" style="width:40px;height:100px;"><div>
<div class="test" style="width:40px;height:100px;"><div>
</div>
.main{
position:relative;
border:1px solid red;
width:140px;
height:400px;
}
.test{
float:left;
border:1px solid silver;
position:relative;
padding:10px;
display:inline-block;
}
Div and its height and width are coming dynamically. I am trying to fit the div width in the layout .2 per on raw.
Please suggest.
The height of the container div should be auto. So, it'll take the optimal space to fit the inner elements.
.main {
...
height: auto;
}
Demo
.main {
border: 1px solid red;
width: 140px;
height: auto;
overflow: hidden;
}
.test {
float: left;
border: 1px solid silver;
position: relative;
padding: 10px;
display: inline-block;
}
<div class="main">
<div class="test" style="width:40px;height:100px"></div>
<div class="test" style="width:20px;height:150px;"></div>
<div class="test" style="width:40px;height:100px;"></div>
<div class="test" style="width:40px;height:100px;"></div>
</div>
If you already use Bootstrap you can use its classes to make 2 items per row
https://jsfiddle.net/3mdrrjf8/1/
<div class="main row">
<div class="test col-md-8 col-xs-6" style="height:100px"></div>
<div class="test col-md-8 col-xs-6" style="height:150px;"></div>
<div class="test col-md-8 col-xs-6" style="height:100px;"></div>
<div class="test col-md-8 col-xs-6" style="height:100px;"></div>
</div>

Auto-scroll to a div when clicking on another div

When I click on one of the smaller divs on the left (inside of the div with the class "smallitems", I want for the div on the right (with the class "items") to auto-scroll to the appropriate larger div.
HTML:
<div class="smallitems">
<div class="col">1</div>
<div class="col"> 2 </div>
<div class="col"> 3</div>
<div class="col">4</div>
<div class="col"> 5 </div>
<div class="col">6 </div>
<div class="col"> 7</div>
<div class="col">8</div>
</div>
<div class="items">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">5</div>
</div>
JavaScript (with JQuery):
$('.smallitems .col').on("click", function(){
//how use scroll items show
});
Example:
This is before I click on a div in the left div ("smallitems").
I've now clicked on the number 5 (<div class="col">5</div>) in the left div. As you can see the right div has scrolled to the 5th div (<div class="item">5</div>).
Similar to the above, I've clicked on the number 4, and subsequently have had the right div auto-scroll to the 4th div.
see jfiddle http://jsfiddle.net/h7bLK/
This can be done with anchors. If you replace your div.cols with anchor tags and add an ID to your div.items like this:
<div class="smallitems">
<a class="col" href="#item1">1</a>
<a class="col" href="#item2">2</a>
. . .
</div>
<div class="items">
<div class="item" id="item1">1</div>
<div class="item" id="item2">2</div>
. . .
</div>
Fiddle link
BONUS: You'll be able to link externally to the correct item.
CONS: If the content is smaller than the frame it is rendered in, the whole frame will scroll.
According to requirement, no-need to use javascript or jquery. Its done only using css.
<div class="main-container">
<div class="smallitems">
<div class="col">1</div>
<div class="col"> 2 </div>
<div class="col last-child">3</div>
<div class="col">4</div>
<div class="col">5 </div>
<div class="col last-child">6 </div>
<div class="col"> 7</div>
<div class="col">8</div>
</div>
<div class="items">
<div class="scroll">
<div class="item" id="one">1</div>
<div class="item" id="two">2</div>
<div class="item" id="three">3</div>
<div class="item" id="four">4</div>
<div class="item" id="five">5</div>
<div class="item" id="six">6</div>
<div class="item" id="seven">7</div>
<div class="item" id="eight">8</div>
</div>
</div>
</div>
**Css** :
.main-container{
margin: 20px auto;
width:960px;
overflow: hidden;
border: 1px solid #bababa;
padding: 5px;
}
.smallitems{
overflow: hidden;
float: left;
width:330px;
border: 1px solid #bababa;
display: table;
padding: 10px;
}
.col a{
display: block;
padding: 41px 0;
text-decoration: none;
}
.col{
float:left;
display: table-cell;
vertical-align: middle;
text-align: center;
font-size: 14px;
font-weight: 700;
cursor: pointer;
border: 1px solid #bababa;
height: 100px;
width: 100px;
margin: 0 10px 10px 0;
}
.items{
float: right;
width:580px;
border: 1px solid #bababa;
overflow-y: hidden;
white-space: nowrap;
padding: 10px;
}
.col:nth-child(3),.last-child{
margin-right: 0;
}
.item{
display: inline-block;
text-align: center;
position:relative;
font-size: 14px;
font-weight: 700;
border: 1px solid #bababa;
height: 440px;
width: 180px;
margin: 0 10px 10px 0;
}
$('.smallitems .col').on("click", function(){
var index = $(this).index();
var items = $('.items');
var item = items.children().eq(index);
items.scrollLeft((item.width() - 50) * index);
});
When you add a new div to the items play around with the value of 50.
<div class="container">
<div class="smallitems">
<div class="col">1</div>
<div class="col"> 2 </div>
<div class="col"> 3</div>
<div class="col">4</div>
<div class="col"> 5 </div>
<div class="col">6 </div>
<div class="col"> 7</div>
<div class="col">8</div>
</div>
<div class="items" id="maindiv"> // set id
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">5</div>
</div>
</div>
$('.smallitems').on("click", function(e){
// get click element text and calculate scrollLeft
var scrollLeft = (parseInt($(e.target).text())-1) * 200;
// use jquery animation function
$('#maindiv').animate({scrollLeft :scrollLeft},1100)
});

Categories

Resources