I have a sidebar which I want to scroll conditionally. I have provided the structure. In the layout both left and right side has lots of content. What I want when a user scroll down, let the both side scroll together. When the bottom of the right section comes visible, I want right section to stop going up, and let the left section keep scrolling. And when the user scrolls up, let the both left and right section scroll up. When the top edge of the right section comes visible, I want right section to stop scrolling anymore and let the left section keep scrolling on its own. How can I achieve this layout?
.main{
width : 100%;
}
.mainBody{
width: calc(100% - 200px);
background-color: pink;
display : inline-block;
}
.mainBody div{
margin-bottom : 500px;
}
.Sidebar{
display : inline-block;
width : 200px;
float: right;
background-color : yellow;
}
.Sidebar div{
margin-bottom : 350px;
}
<div class="main">
<div class="mainBody">
<div>Hello World 1</div>
<div>Hello World 2</div>
<div>Hello World 3</div>
<div>Hello World 4</div>
<div>Hello World 5</div>
</div>
<div class="Sidebar">
<div>Sidebar Section 1</div>
<div>Sidebar Section 2</div>
<div>Sidebar Section 3</div>
<div>Sidebar Section 4</div>
<div>Sidebar Section 5</div>
</div>
</div>
you mean this ?
$(window).on("scroll", function() {
wh = $(this).height(),
st = $(this).scrollTop(),
side = $(".Sidebar"),
sh = side.outerHeight();
if( (st + wh) >= sh ) {
side.addClass("fixed");
} else {
side.removeClass("fixed");
}
})
.main{
width : 100%;
}
.mainBody{
width: calc(100% - 200px);
background-color: pink;
display : inline-block;
}
.mainBody div{
margin-bottom : 500px;
}
.Sidebar{
display : inline-block;
width : 200px;
float: right;
background-color : yellow;
}
.Sidebar div{
margin-bottom : 350px;
}
.Sidebar.fixed{
position: fixed;
right: 0;
bottom: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="main">
<div class="mainBody">
<div>Hello World 1</div>
<div>Hello World 2</div>
<div>Hello World 3</div>
<div>Hello World 4</div>
<div>Hello World 5</div>
</div>
<div class="Sidebar">
<div>Sidebar Section 1</div>
<div>Sidebar Section 2</div>
<div>Sidebar Section 3</div>
<div>Sidebar Section 4</div>
<div>Sidebar Section 5</div>
</div>
</div>
If you want to stop scrolling right section when its reach bottom , you need to set max-height of left section to that right section height , also set overflow property ....
var sidebarHeight = $('.Sidebar').height();
$(".mainBody").css({"max-height": sidebarHeight, "overflow-y":"scroll"});
.main{
width : 100%;
}
.mainBody{
width: calc(100% - 200px);
background-color: pink;
display : inline-block;
}
.mainBody div{
margin-bottom : 500px;
}
.Sidebar{
display : inline-block;
width : 200px;
float: right;
background-color : yellow;
}
.Sidebar div{
margin-bottom : 350px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="main">
<div class="mainBody">
<div>Hello World 1</div>
<div>Hello World 2</div>
<div>Hello World 3</div>
<div>Hello World 4</div>
<div>Hello World 5</div>
</div>
<div class="Sidebar">
<div>Sidebar Section 1</div>
<div>Sidebar Section 2</div>
<div>Sidebar Section 3</div>
<div>Sidebar Section 4</div>
<div>Sidebar Section 5</div>
</div>
</div>
First of all get the height of sidebar $('#sidebar').height() and decrease window height $(window).height(); from sidebar height then you can apply/add fixed class .fixed-right-bar. Like given below example:-
var sidebarHeight = $('#sidebar').height();
var documentHeight = $(window).height();
$(window).on('scroll', function(){
if($(window).scrollTop() > sidebarHeight-documentHeight){
$('#sidebar').addClass('fixed-right-bar');
}
else{
$('#sidebar').removeClass('fixed-right-bar');
}
});
.main{
width : 100%;
}
.mainBody{
width: calc(100% - 200px);
background-color: pink;
display : inline-block;
}
.mainBody div{
margin-bottom : 500px;
}
.Sidebar{
display : inline-block;
width : 200px;
float: right;
background-color : yellow;
}
.Sidebar div{
margin-bottom : 350px;
}
.fixed-right-bar{ position:fixed; right:0; bottom:0;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="main">
<div class="mainBody">
<div>Hello World 1</div>
<div>Hello World 2</div>
<div>Hello World 3</div>
<div>Hello World 4</div>
<div>Hello World 5</div>
</div>
<div class="Sidebar" id="sidebar">
<div>Sidebar Section 1</div>
<div>Sidebar Section 2</div>
<div>Sidebar Section 3</div>
<div>Sidebar Section 4</div>
<div>Sidebar Section 5</div>
</div>
</div>
Related
I m creating ticker in which the divs will be scrolling infinitely vertically on next/prev buttons ... I have created it but there is a small issue in it .. when i click on prev button the divs scrolls upward on first click and after that it scrolls downward and same goes for next button as well ..Someone help please
var buttons = $('.next-prev');
$(buttons).each(function(){
$(this).click(function(){
var id = $(this).attr('id');
if(id=="next"){
$('#scroll-div').stop().animate({scrollTop:40},400,'swing',function(){
$(this).scrollTop(0).find('div:last').after($('div:first', this));
});
}
else {
$('#scroll-div').stop().animate({scrollTop:40},400,'swing',function(){
$(this).scrollTop(40).find(' div:first').before($(' div:last', this));
});
}
})
})
* {
box-sizing: border-box;
}
#scroll-div {
overflow: hidden;
width: 300px;
height: 250px;
background: green;
padding: 10px;
}
#scroll-div div {
display: block;
height: 30px;
padding: 10px 10px;
margin-bottom: 10px;
background: cyan;
}
.item:last-child {
margin-bottom: 0px;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<button class="next-prev" id="next">
up
</button>
<button class="next-prev" id="prev">
down
</button>
</div>
<div id="scroll-div">
<div>div 1</div>
<div>div 2</div>
<div>div 3</div>
<div>div 4</div>
<div>div 5</div>
<div>div 6</div>
<div>div 7</div>
<div>div 8</div>
<div>div 9</div>
<div>div 10</div>
</div>
var buttons = $('.next-prev');
$('#scroll-div').prepend($('#scroll-div').find('div:last-child')); // prepend last element
$('#scroll-div').scrollTop(40); // scroll div to position 40 so first (div 10) not visible
$(buttons).each(function(){
$(this).click(function(){
var id = $(this).attr('id');
if(id=="next"){
$('#scroll-div').append($('#scroll-div').find('div:first-child')); //do modification first
} else {
$('#scroll-div').prepend($('#scroll-div').find('div:last-child'));
}
$('#scroll-div').stop().animate({scrollTop:40},400,'swing'); // then scroll
})
})
* {
box-sizing: border-box;
}
#scroll-div {
overflow: hidden;
width: 300px;
height: 250px;
background: green;
padding: 10px;
}
#scroll-div div {
display: block;
height: 30px;
padding: 10px 10px;
margin-bottom: 10px;
background: cyan;
}
.item:last-child {
margin-bottom: 0px;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<button class="next-prev" id="next">
up
</button>
<button class="next-prev" id="prev">
down
</button>
</div>
<div id="scroll-div">
<div>div 1</div>
<div>div 2</div>
<div>div 3</div>
<div>div 4</div>
<div>div 5</div>
<div>div 6</div>
<div>div 7</div>
<div>div 8</div>
<div>div 9</div>
<div>div 10</div>
</div>
I have a requirement to create a News section on a webpage (it's SharePoint, but that's probably not terribly relevant) which looks something like the image below.
My issue is that HTML will be dynamically generated from a list of the news items, so the code for each item will be the same - ie. I don't think I can add code to differentiate between the left hand column item and the right hand column items.
The code is formatted with handlebars.js, but the lack of logic there seems to prevent me from doing it there?
So using a simple {{#each items}} in the handlebars, I end up with something like this:
<div class="newsContainer">
<div class="newsItem">
<img src="image1"/>
<div class="newsTitle">Headline 1</div>
<div class="newsSummary">Summary 1</div>
</div>
<div class="newsItem">
<img src="image2"/>
<div class="newsTitle">Headline 2</div>
<div class="newsSummary">Summary 2</div>
</div>
<div class="newsItem">
<img src="image3"/>
<div class="newsTitle">Headline 3</div>
<div class="newsSummary">Summary 3</div>
</div>
<div class="newsItem">
<img src="image4"/>
<div class="newsTitle">Headline 4</div>
<div class="newsSummary">Summary 4</div>
</div>
</div>
So my challenge is to create the layout below from the code above using either just CSS, or CSS and JavaScript.
I've made limited progress with ":first-of-type", but I'm wondering if something like FlexBox may be another option?
Thanks!
You can archieve the desired layout by using floating divs. I wrote a little example for you.
I didn't edit any of the HTML you provided. So you could just copy and paste the CSS from below.
See below snippet.
* {
box-sizing: border-box;
}
/**
This is a clearfix. Floated divs have to be cleared, else the layout will mess up
*/
.newsContainer::before,
.newsContainer::after,
.newsContainer .newsItem::before,
.newsContainer .newsItem::after {
display: table;
content: " ";
clear: both;
}
.newsContainer .newsItem {
float: left;
}
.newsContainer .newsItem:first-child {
width: 50%;
}
/**
Margin-left 5% acts as spacing
Put all divs near the first child, except :first-child using CSS :not() selector
*/
.newsContainer .newsItem:not(:first-child) {
width: 45%;
margin-left: 5%;
}
/**
Overwrite above CSS, now set float right on the 4th and 5th divs. You can add
more divs `.newsItem:nth-child(6) ... etc` if more divs are present.
Set margin left value same as .newsContainer .newsItem:first-child width
*/
.newsContainer .newsItem:nth-child(5) {
float: right;
margin-left: 50%;
}
/**
This is just for responive images
*/
.newsContainer .newsItem img {
max-width: 100%;
max-height: 100%;
}
.newsContainer .newsItem .newsTitle > a,
.newsContainer .newsItem .newsSummary {
color: #969696;
}
.newsContainer .newsItem .newsTitle > a {
font-size: 28px;
text-decoration: none;
}
.newsContainer .newsItem .newsSummary {
font-size: 16px;
}
.newsContainer .newsItem > div {
padding: 0 15px 15px;
}
.newsContainer .newsItem:not(:first-child) > * {
float: left;
width: 50%;
}
<div class="newsContainer">
<div class="newsItem">
<img src="https://via.placeholder.com/600x500"/>
<div class="newsTitle">Headline 1</div>
<div class="newsSummary">Summary 1</div>
</div>
<div class="newsItem">
<img src="https://via.placeholder.com/200x200"/>
<div class="newsTitle">Headline 2</div>
<div class="newsSummary">Summary 2</div>
</div>
<div class="newsItem">
<img src="https://via.placeholder.com/200x200"/>
<div class="newsTitle">Headline 3</div>
<div class="newsSummary">Summary 3</div>
</div>
<div class="newsItem">
<img src="https://via.placeholder.com/200x200"/>
<div class="newsTitle">Headline 4</div>
<div class="newsSummary">Summary 4</div>
</div>
<div class="newsItem">
<img src="https://via.placeholder.com/200x200"/>
<div class="newsTitle">Headline 5</div>
<div class="newsSummary">Summary 5</div>
</div>
</div>
You can create your own columnar layout to achieve this:
.newsContainer {
width: 100%;
}
.col {
position: relative;
float: left;
width: 50%;
}
<div class="newsContainer">
<div class="col">
<div class="newsItem">
<img src="image1" />
<div class="newsTitle">Headline 1</div>
<div class="newsSummary">Summary 1</div>
</div>
</div><!--End Col 1-->
<div class="col">
<div class="newsItem">
<img src="image2" />
<div class="newsTitle">Headline 2</div>
<div class="newsSummary">Summary 2</div>
</div>
<div class="newsItem">
<img src="image3" />
<div class="newsTitle">Headline 3</div>
<div class="newsSummary">Summary 3</div>
</div>
<div class="newsItem">
<img src="image4" />
<div class="newsTitle">Headline 4</div>
<div class="newsSummary">Summary 4</div>
</div>
</div><!--End Col 2-->
</div>
I am trying to convert my site to mobile friendly. The easiest way I believe is to hide certain sections when in mobile view and just show the MAIN CONTENT. The site is general divided up like this:
<div class="main">
<div id="header_holder">
HEADER CONTENT
</div>
<div class="side">
<cfinclude template="menu.cfm">
<div class="sidebot">Title 1</div>
<div class="space10">image 1</div>
<div class="space10">image 2</div>
<div class="space10">image 3</div>
<div class="sidebot">Title 2</div>
<div class="lineG2"></div>
<div class="sidebot">Title 3</div>
</div>
<div class="content">
<div class="cLeft">
MAIN CONTENT
</div>
<div class="cRight">
right content 1
right content 2
<cfinclude template="ads.cfm">
</div>
</div>
<div class="footer">
footer content
</div>
</div>
The CSS:
.main{width:960px;margin:0 auto;overflow:hidden;zoom:1}
.side{
float:left;
width:110px;
margin-right:10px;
}
.sidebot{float:left;width:110px;padding-top:20px;font-weight:bold;}
.content{width:840px;float:left}
.content .cLeft{float:left;width:530px;margin-right:10px;}
.content .cRight{float:left;width:300px;margin-bottom:10px;}
.lineGrey {
border-top: 1px solid #C1C1C1;
list-style-type: none;
padding:20px 0px;
overflow: hidden;
width: 100%;
height: 220px;
}
.space10{float:left;margin-top:10px;}
I want to hide the left side ("side") and right side ("cRight") leaving the MAIN CONTENT intact when in mobile view. According to instructions I am supposed to be able to do so by using #media for example like this:
#media screen and (max-width: 530px) {
.side{
visibility: hidden;
clear: both;
display: none;
float:left;
width:110px;
margin-right:10px;
}
}
Well, it does hide the "side" in mobile mode i.e. when it is less than 530. However, it messed up the original desktop format. The "side" menu is displayed properly on the left, but the rest of the "side" content:
<div class="sidebot">Title 1</div>
<div class="space10">image 1</div>
<div class="space10">image 2</div>
<div class="space10">image 3</div>
<div class="sidebot">Title 2</div>
<div class="lineG2"></div>
<div class="sidebot">Title 3</div>
went to the top of the left main content "cLeft". Similar issue with the "cRight" when in desktop mode when I wrap it with:
#media screen and (max-width: 530px) {
.content .cRight{
visibility: hidden;
clear: both;
display: none;
float:left;
width:300px;
margin-bottom:10px;
}
}
some of the cRight content
right content 2
<cfinclude template="ads.cfm">
went to the bottom of the left main content "cLeft". I am at lost as to what happened. Why would it mess up the desktop mode format?
Q2. If we solve this will this work with older version of CSS? i.e. in older browser IE 7?
Any help is appreciated.
I'm not 100% sure what your question is but if you're trying to get rid of content, cRight and side div , then just paste this code here below your Desktop CSS.
CSS is read by the browser top to bottom so if you add all that other code below your display:none, then you're gonna have some different outcomes than display:none because CSS is read top to bottom.
Hope this helps
#media screen and (max-width: 530px) {
.side{
visibility: hidden;
clear: both;
float:left;
width:110px;
margin-right:10px;
display: none;
}
.content .cRight{
visibility: hidden;
clear: both;
float:left;
width:300px;
margin-bottom:10px;
display: none;
}
}
I am using the fullPage plugin and everything worked like expected, but then I realized, when I resize the window, there is an unwanted animation. The div container is moving and after a delay it´s getting in the desired position.
Here is my Code:
//HTML structure
<div id="fullpage">
<div class="section">
<div class="slide">Two 1</div>
<div class="slide">Two 2</div>
<div class="slide active">
<div class="slide-container"></div>
<div class ="slide-container skills"></div>
</div>
</div>
</div>
//CSS
.section {
text-align:center;
}
.slide-container {
float: left;
display: inline-block;
width: 50%;
height: 100%;
}
.skills {
background-color: #CDFF00;
}
I haven't made changes to the fullpage plugin except loopHorizontal: false.
Example on jsfiddle:
http://jsfiddle.net/oodLzLwv/1/
I have two rows of data (green) and a header (red), which should be visible at all times:
Check out the example I already have:
http://jsfiddle.net/j9C8R/33/
Now the red header scrolls away together with the content, but it should stick to where it is now, but scroll vertically with the content (MS Excel style).
How can this be achieved (preferably with only CSS).
UPDATE: It is important that the red headers scroll vertically along with the corresponding content but stick to the left edge when scrolling horizontally.
.main {
background-color: blue;
overflow: scroll;
height: 200px;
width: 400px;
}
.row {
height: 50px;
overflow: scroll;
clear: both;
width: 1000px;
background-color: yellow;
}
.sticky,
.content {
float: left;
width: 150px;
border: 1px solid black;
}
.sticky {
background-color: red;
}
.content {
background-color: green;
}
<div class="main">
<div class="row">
<div class="sticky">Sticky header A</div>
<div class="content">ContentA</div>
<div class="content">ContentA</div>
<div class="content">ContentA</div>
<div class="content">ContentA</div>
</div>
<div class="row">
<div class="sticky">Sticky header B</div>
<div class="content">ContentB</div>
<div class="content">ContentB</div>
<div class="content">ContentB</div>
<div class="content">ContentB</div>
</div>
<div class="row">
<div class="sticky">Sticky header C</div>
<div class="content">ContentC</div>
<div class="content">ContentC</div>
<div class="content">ContentC</div>
<div class="content">ContentC</div>
</div>
<div class="row">
<div class="sticky">Sticky header D</div>
<div class="content">ContentD</div>
<div class="content">ContentD</div>
<div class="content">ContentD</div>
<div class="content">ContentD</div>
</div>
<div class="row">
<div class="sticky">Sticky header E</div>
<div class="content">ContentE</div>
<div class="content">ContentE</div>
<div class="content">ContentE</div>
<div class="content">ContentE</div>
</div>
</div>
UPDATE
please note the below is now a little out of date as we have css position sticky
Original Post
I do not think it is possible to achieve your goal through pure css as items that are sticky usually use position:fixed which unfortunately fixes them relative to the viewport.
with the use of javascript (in this case the jquery library) and absolute positioning, you should be able to achieve what you are after:
$('.main').scroll(function() {
$(this).find('.sticky').css('left', $(this).scrollLeft());
});
.main {
background-color:blue;
overflow:scroll;
height:200px;
width:400px;
}
.row {
height:50px;
overflow:scroll;
clear:both;
width:1000px;
position:relative;
background-color:yellow;
padding-left:150px;
box-sizing:border-box;
}
.sticky, .content {
float:left;
width:150px;
border:1px solid black;
}
.sticky {
background-color:red;
position:absolute; left:0; top:0;
}
.content {
background-color:green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="main">
<div class="row">
<div class="sticky">I should stick to the left border</div>
<div class="content">Content</div>
<div class="content">Content</div>
<div class="content">Content</div>
<div class="content">Content</div>
</div>
<div class="row">
<div class="sticky">I should stick to the left border</div>
<div class="content">Content</div>
<div class="content">Content</div>
<div class="content">Content</div>
<div class="content">Content</div>
</div>
<div class="row">
<div class="sticky">I should stick to the left border</div>
<div class="content">Content</div>
<div class="content">Content</div>
<div class="content">Content</div>
<div class="content">Content</div>
</div>
<div class="row">
<div class="sticky">I should stick to the left border</div>
<div class="content">Content</div>
<div class="content">Content</div>
<div class="content">Content</div>
<div class="content">Content</div>
</div>
<div class="row">
<div class="sticky">I should stick to the left border</div>
<div class="content">Content</div>
<div class="content">Content</div>
<div class="content">Content</div>
<div class="content">Content</div>
</div>
</div>
Ok I've scrapped your thing and have made a complete new one, I've just not wrapped up things inside a position relative container but you can manage to do it atleast
The things are easy for vertical scroll but if you expect horizontal scroll and move headers along, (CSS Wont Just Do It)
Demo
CSS
.head {
background-color: #f00;
width: 300px;
position: absolute;
left: 100px;
}
.head table {
width: 100%;
}
.body {
position: relative;
left: 100px;
top: 20px;
width: 300px;
height: 50px;
overflow-y: auto;
}
.body table {
width: 100%;
}
.body td {
width: 100px;
}
.head table td {
width: 100px;
}
.left {
position: absolute;
background-color: #0f0;
width: 90px;
top: 40px;
}