I've a part of code on my website. Some time it can happen that the line breaks if the code don't fit in the parent element anymore:
If this happens I want to break all lines instead because it looks ugly when one part is broken and the other don't.
Remind
I can have a least 20 elements in one list.
Update
This is the part of my code which I all need to wrap if one of them wraps:
.elements-list {
display: -webkit-box;
display: flex;
display: -ms-flexbox;
list-style: none outside;
}
.list-entry {
display: -webkit-box;
display: flex;
display: -ms-flexbox;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
list-style: none outside;
padding-right: 8px;
max-width: 200px;
}
span.single-detail span {
letter-spacing: 1px;
display: -webkit-inline-box;
display: inline-flex;
display: -ms-inline-flexbox;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
}
<ul class="elements-list">
<li class="list-entry">
<span class="single-detail">
<span>Abgabefrist:</span>
<span>22.02.2222</span>
</span>
<span class="single-detail">
<span>Entlohnung:</span>
<span>2.222,00 €</span>
</span>
</li>
<li class="list-entry">
<span class="single-detail">
<span>Abgabefrist:</span>
<span>22.02.2222</span>
</span>
<span class="single-detail">
<span>Entlohnung:</span>
<span>20.222,00 €</span>
</span>
</li>
<li class="list-entry">
<span class="single-detail">
<span>Abgabefrist:</span>
<span>22.02.2222</span>
</span>
<span class="single-detail">
<span>Entlohnung:</span>
<span>22.000.222,00 €</span>
</span>
</li>
</ul>
I don't think you can solve this with CSS alone. You can solve it with JavaScript.
One way would be to constantly monitor the elements and see if one of them wrapped. But then, once wrapped you will never unwrap, it's not responsive.
So this is my alternative:
By putting the value inside inline-block elements, you can align the widths of the elements. This way, when one element wraps, they will all wrap, because they simply won't fit anymore.
Advantages of this solution:
It's responsive, responds to browser resizing.
Only requires JavaScript on load. Sizing and wrapping is handled by CSS once the widths are set, so it's fairly lightweight.
Disadvantages:
You will need to recalculate the widths if you change the content of the elements, or if you have dynamic font sizing (I hope not).
It's not pixel perfect, it seems. Maybe it can be tuned (for instance by giving the left element also a width in whole pixels), or otherwise, maybe you'll forgive me this pixel. ;)
window.addEventListener('DOMContentLoaded', function(){
var rows = document.querySelectorAll('.row');
// First loop to find which line is the widest.
var widest = 0;
for(r=0; r<rows.length; r++) {
console.log(r);
var width = rows[r].querySelector('.col1').offsetWidth +
rows[r].querySelector('.col2').offsetWidth;
if (width > widest) widest = width;
}
// second loop to set the width of col2, so they all
// get the same width.
for(r=0; r<rows.length; r++) {
rows[r].querySelector('.col2').style.width =
(widest - rows[r].querySelector('.col1').offsetWidth) + 'px';
}
});
/* This is needed */
.col2 {
display: inline-block;
}
/* This is just for show */
.col1 {
padding-right: 1em;
}
span {
box-sizing: border-box;
border: 1px solid grey;
}
<!-- hacky div/span table, since there is no HTML in the question -->
<div class="row"><span class="col1">The time</span><span class="col2">2018-12-22 12:34</span></div>
<div class="row"><span class="col1">Total price here</span><span class="col2">$ 5,-</span></div>
You either need to set the css property white-space: nowrap; on the text parent element so no text wraps for that class or you could add the <br> on the HTML after the name of the element so it breaks every time, code is needed so we can be more specific in finding a solution.
Well, easiest would be to create "abgabefrist:01/01/0001" as two elements instead of one and then add display flex to the parent. so when the screen shrinks, the element comes below another.
Below mentioned code fine, tested on codepen.
.dates div {
display: flex;
flex-wrap: wrap;
}
<div class="main">
<div class="dates">
<div><span>abgabefrist:</span>
<span>01/01/0001</span></div>
<div><span>abgabefrist:</span>
<span>02/02/0002</span></div>
</div>
<div class="btns">
<button> Button One</button>
<button> Button Two </button>
</div>
</div>
Related
I have two divs. Inside each div, there are two divs:
<div class="hide">
<div>
Variable size
</div>
<div>
Text1 (also variable size)
</div>
</div>
<div class="hide">
<div>
Different variable size
</div>
<div>
Text2 (also variable size)
</div>
</div>
If the screen is too small, I want the texts to disappear:
To do it, I used
.hide {
display: flex;
height: 100px;
flex-wrap: wrap;
overflow: hidden;
}
However, if the 1st text is too big, but the second is not, I have something like that:
And I'd like them to be hidden simultaneously.
Is there a way (no jQuery) to do it? Preferably with CSS or SASS, but JS (I use Angular) would also be acceptable.
Use display flex like this
.hide { height: 100px; display: flex; flex-wrap: wrap; overflow: hidden; }
I have a set of tags, that I want to show in the client. However, sometimes you might have too many tags and you want to show only one row of tags maximized to your body's width without setting a fixed number of columns or item width, and adding a show more button at the end of the tag list with the same style as a tag.
I have achieved this using Javascript in my Angular project by doing the following:
Find out the width of your tags container dynamically, with ViewChild on my content container:
let contentWidth = this.contentContainer.nativeElement.clientWidth;
Calculate the text width of the see more button and use it to calculate the new content width minus see more button width:
Calculating text function does the following:
const canvas = document.createElement('canvas'); // create a canvas
const context = canvas.getContext('2d'); // get the context
context.font = '12px avertastd-bold'; // set up your font and size
And calculate the text width:
const seeMoreButtonWidth = context.measureText(seeMoreButtonText).width;
Create a new array variable 'previewTags' which will hold the tags that are visible when the tags body is in collapsed state, and fill in as many tags as you can by calculating each tag's width with it's content text you receive from the API by checking if the next tag + its padding (static value) fits into the width.
(Not runnable here)
for (const tag of this.data.tags) {
const width = context.measureText(tag).width;
if (contentWidth - (width + this.tagsPadding) > 0) {
previewTags.push({text: tag});
contentWidth -= (width + this.tagsPadding);
} else {
break;
}
}
Push the see more button at the end of previewTags list:
previewTags.push({text: seeMoreButtonText, isButton: true});
And it looks like this in the html:
<ng-container *ngFor="let tag of previewTags">
<div class="tag" [ngClass]="{'see-more-button': tag.isButton}">{{tag.text}}</div>
</ng-container>
Output:
Resize:
As you see, now the tags are flexiable (this code does not include the show more functionality).
After giving you this background and understanding of what I am doing, I would love to ask if this is possible to achieve with css or less JavaScript intervation?
Something like this could be a pure css solution if your tags have a constant height. I just let the flex-list wrap around and then don't show the overlap.
.content_wrapper {
display: flex;
justify-content: flex-start;
flex-direction: rows;
}
.tag_wrapper {
display: flex;
justify-content: flex-start;
flex-direction: rows;
flex-wrap: wrap;
width: 80%;
height: 32px;
overflow: hidden;
}
.tag_wrapper div {
width:100px;
height:30px;
border: 1px solid black;
}
button {
flex-grow: 4;
}
<div class="content_wrapper">
<div class=tag_wrapper>
<div>Tag1</div>
<div>Tag2</div>
<div>Tag3</div>
<div>Tag4</div>
<div>Tag5</div>
<div>Tag6</div>
<div>Tag7</div>
<div>Tag8</div>
<div>Tag9</div>
</div>
<button>See more</button>
You could probably make the "See more" button solution more elegant, to not have as much white space but I'll leave that to you :)
Here is some javascript to remove the see-more button if it's not needed.
(OBS) this only works if all the tags are the exact same width and have the same margin. I did this to avoid looping through all values and checking their width individually.
(I know the list is in the wrong order, I made it like that to get the see-more button fit in well without having to tinker a bunch.
function getWidthWithMargin(elem) {
var style = elem.currentStyle || window.getComputedStyle(elem)
margin = parseFloat(style.marginLeft) + parseFloat(style.marginRight)
return(elem.getBoundingClientRect().width + margin)
}
function handleWindowSizeChange() {
let tags = document.getElementsByClassName("tag");
if(tags.length != 0)
{
let tag_width = getWidthWithMargin(tags[0]);
if(tags[0].parentElement.getBoundingClientRect().width/tag_width > tags.length) {
document.getElementById("see-more-button").style.display = "none";
}
else{
document.getElementById("see-more-button").style.display = "block";
}
}
}
window.onload = handleWindowSizeChange;
window.onresize = handleWindowSizeChange;
.content_wrapper {
}
.tag_wrapper {
display: flex;
justify-content: flex-start;
flex-direction: row-reverse;
flex-wrap: wrap;
width: 100%;
height: 32px;
overflow: hidden;
}
.tag_wrapper div {
min-width:100px;
height:30px;
border: 1px solid black;
margin: 10px;
}
.tag_wrapper button {
height:30px;
flex-grow: 50;
}
<div class="content_wrapper">
<div class=tag_wrapper>
<button id="see-more-button">See more</button>
<div class="tag">Tag1</div>
<div class="tag">Tag2</div>
<div class="tag">Tag3</div>
<div class="tag">Tag4</div>
<div class="tag">Tag5</div>
<div class="tag">Tag6</div>
<div class="tag">Tag7</div>
<div class="tag">Tag8</div>
</div>
Take a look at this example: https://jsfiddle.net/qpysmb9t/
Whenever text in the contentEditable element becomes bigger that the max-width of the div(try typing some long text), than the left part gets hidden and what's on the right is shown. This is okay while you type, but on focus out I'd like to reverse this and show text from the beginning.
<div tabindex="-1" contenteditable="true" class="name-data">This is test</div>
.name-data{
max-width:180px;
white-space: nowrap;
overflow-x: hidden;
}
The usual answer is to move caret position to the start, however that does not move the text along the way and it also messes with element not focusing out anymore. Check it out: https://jsfiddle.net/qpysmb9t/1/
What do you recommend that I do?
A dash of JavaScript helps. When the div loses focus we can use scrollLeft to get back to the begin position.
//scroll the text back to the beginning when focus is lost
document.querySelector("div.name-data[contenteditable='true']").addEventListener("blur", function(e){
this.scrollLeft = "0px";
}, true);
.name-data{
max-width:180px;
white-space: nowrap;
overflow-x: hidden;
border: 1px solid #949494;
}
<div tabindex="-1" contenteditable="true" class="name-data">This is test</div>
IDEA: Make your div display: flex and toggle justify-content propertive when user focus out to force browser re-paint the content
CSS only solution:
.project-name-data {
max-width: 180px;
white-space: nowrap;
overflow-x: hidden;
display: flex;
justify-content: flex-start;
align-items: center;
flex-wrap: wrap;
border: solid 1px gray;
}
.project-name-data:focus{
justify-content: flex-end;
}
<div tabindex="-1" contenteditable="true" #projectName class="project-name-data">This is test</div>
I like CSS only solution but it weird because the div content have different align from two state focus and normal. So i add a bit javscript to fix it
Javascript solution:
document.getElementsByClassName("project-name-data")[0].addEventListener("focusout", function() {
this.style.justifyContent = "flex-end";
// Wait a tick then change the justifyContent back to force browser re-paint
setTimeout(() => {
this.style.justifyContent = "flex-start";
}, 0)
});
.project-name-data {
max-width: 180px;
white-space: nowrap;
overflow-x: hidden;
display: flex;
justify-content: flex-start;
align-items: center;
flex-wrap: wrap;
border: solid 1px gray;
}
<div tabindex="-1" contenteditable="true" #projectName class="project-name-data">This is test</div>
For DIV contenteditable, we need to fix a scroll left bug. Combined both Duannx and Mouser answers into another example (my own project).
// Fix DIV contenteditable scroll left bug
var elements = document.querySelectorAll('div[contenteditable="true"]');
for (let i = 0; i < elements.length; i++)
{
elements[i].addEventListener('focus', setScrollLeft, true); // The handler is executed in the capturing phase
elements[i].addEventListener('blur', setScrollCenter, true); // The handler is executed in the capturing phase
}
function setScrollLeft()
{
this.scrollLeft = '0px';
this.style.justifyContent = 'flex-start';
}
function setScrollCenter()
{
this.scrollLeft = '50%';
this.style.justifyContent = 'center';
}
My problem is that I want the flexbox with variable range width, and all works well, but not on the last row. I want the same dimension for all children even where the row is not full of children (the last row).
#products-list {
position:relative;
display: flex;
flex-flow: row wrap;
width:100%;
}
#products-list .product {
min-width:150px;
max-width:250px;
margin:10px 10px 20px 10px;
flex:1;
}
I created a dynamic situation in jsFiddle
My flex divs can shrink until 150px and grow up to 250px, but all must be with the same size (and obviously I want a CSS solution, with JS I know the way).
Unfortunately, in the current iteration of flexbox (Level 1), there is no clean way to solve the last-row alignment problem. It's a common problem.
It would be useful to have a flex property along the lines of:
last-row
last-column
only-child-in-a-row
alone-in-a-column
This problem does appear to be a high priority for Flexbox Level 2:
CSS Working Group Wiki - Specification Issues and Planning
https://lists.w3.org/Archives/Public/www-style/2015Jan/0150.html
Although this behavior is difficult to achieve in flexbox, it's simple and easy in CSS Grid Layout:
Equal width flex items even after they wrap
In case Grid is not an option, here's a list of similar questions containing various flexbox hacks:
Properly sizing and aligning the flex item(s) on the last row
Flex-box: Align last row to grid
Flexbox wrap - different alignment for last row
How can a flex item keep the same dimensions when it is forced to a new row?
Selector for an element alone in a row?
Aligning elements in last flexbox row
How can I allow flex-items to grow while keeping the same size?
Left-align last row of flexbox using space-between and margins
Inconsistent margin between flex items on last row
How to keep wrapped flex-items the same width as the elements on the previous row?
How to align left last row/line in multiple line flexbox
Last children of grid get giant gutter cause of flexbox space-between
Managing justify-content: space-between on last row
Flexbox space between behavior combined with wrap
Possible to use CSS Flexbox to stretch elements on every row while maintaining consistent widths?
As a quick and dirty solution one can use:
.my-flex-child:last-child/*.product:last-child*/ {
flex-grow: 100;/*Or any number big enough*/
}
You could try using grid instead of flexbox here:
#products-list {
display: grid;
grid-gap: 5px;
grid-template-columns: repeat(auto-fit, minmax(100px, 250px)); //grid automagic
justify-content: start; //start left
}
Fiddle link
There is a great solution that works always.
add a div with class product (The same class for other items that are under flex) and add a style for this div:height:0px;
you need to add as many dives that are possible to be in one row.
<div class="product" style="height:0px">
as many that can be in one row.
That's all. Works always.
If all your rows have the same number of items, you can use :nth-last-child. For example, if all the rows have 3 items, you can do something like this to remove the margin of the last 3 items:
.container{
display: flex;
flex-wrap: wrap;
background: yellow;
}
.item{
width: calc((100% - 2*10px)/3);
height: 50px;
background: blue;
color: white;
margin-right: 10px;
margin-bottom: 10px;
padding: 5px;
box-sizing: border-box;
}
/* last item of each row */
.item:nth-child(3n){
margin-right: 0;
font-size: 150%;
}
/* last 3 items */
.item:nth-last-child(-n+3){
margin-bottom: 0;
background: green;
}
<div class="container">
<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>
A simple trick adds a flexible space to fill the rest of the last row:
#products-list{
display:flex;
flex-flow: row wrap;
justify-content:space-between;
}
#products-list::after {
content: "";
flex: auto;
flex-basis: 200px;/*your item width*/
flex-grow: 0;
}
But you shouldn't use margins on items then. Rather wrap them into containers with padding.
I used this workaround, even if it's not very elegant and it doesn't use the power of Flexbox.
It can be carried out on the following conditions:
All the items have the same width
The items have a fixed width
You use SCSS/SASS (can be avoided though)
If this is the case, you can use the following snippet:
$itemWidth: 400px;
$itemMargin: 10px;
html, body {
margin: 0;
padding: 0;
}
.flex-container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
margin: 0 auto;
border: solid 1px blue;
}
#for $i from 1 through 10 {
#media only screen and (min-width: $i * $itemWidth + 2 * $i * $itemMargin) {
.flex-container {
width: $i * $itemWidth + 2 * $i * $itemMargin;
}
}
}
.item {
flex: 0 0 $itemWidth;
height: 100px;
margin: $itemMargin;
background: red;
}
<div class="flex-container">
<div class="item"></div>
<div class="item" style="flex: 500 0 200px"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
Here I have created an example on codepen which also implements margin.
The second and the third conditions can be avoided respectively using css variables (if you decided to provide support for it) and compiling the above scss snippet.
Well, it's true, we could do it also before flexbox, but display: flex can be still essential for a responsive design.
I was facing this same issue where I wanted to have a variable number of items in a resizable container.
I wanted to use all of the horizontal space, but have all of the flex items at the same size.
I ultimately came up with a javascript approach that dynamically added padding spacers as the container was resized.
function padLastFormRow() {
let topList = [];
let nSpacersToAdd = 0;
$('#flexContainer').find('.formSpacer').remove();
$('#flexContainer').find('.formItem').each(function(i, formItem) {
topList.push($(formItem).position().top);
});
let allRowLengths = getFlexLineLengths(topList);
let firstRowLength = allRowLengths[0];
let lastRowLength = allRowLengths[((allRowLengths.length) - 1)];
if (lastRowLength < firstRowLength) {
nSpacersToAdd = firstRowLength - lastRowLength ;
}
for (var i = 1; i <= nSpacersToAdd; i ++) {
$('#flexContainer').append(formSpacerItem);
}
}
Please see my Fiddle:
http://jsfiddle.net/Harold_Buchman/z5r3ogye/11/
I was having a similar challenge with menu rows. I wanted more spacing on the top of the second row of menu items.
The use of flex-box's row-gap worked well.
https://developer.mozilla.org/en-US/docs/Web/CSS/row-gap
.menu {
display: flex;
flex-wrap: wrap;
row-gap: 10px;
}
This added a margin-top type effect to menu items were wrapped to the second line.
If all your rows have the same number of items, you can use :nth-last-child. For example, if all the rows have 3 items, you can do something like this:
.container{
display: flex;
flex-wrap: wrap;
background: yellow;
}
.item{
width: calc((100% - 2*10px)/3);
height: 50px;
background: blue;
color: white;
margin-right: 10px;
margin-bottom: 10px;
padding: 5px;
box-sizing: border-box;
}
// last item of each row
.item:nth-child(3n){
margin-right: 0;
background: green;
}
// last 3 items
.item:nth-last-child(-n+3){
margin-bottom: 0;
font-size: 150%;
}
<div class="container">
<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>
I am new to jQuery and am teaching myself as I go but am struggling to figure out how to indicate that on up scroll the white navigation background moves up to show the white navigation text on panel 1?
bartaile.com is what I am using as inspiration & the changes I'm making to bartaile's navigation are---> after the user scrolls past the first panel the navigation hides, only when the user scrolls up does the navigation show again, when panel 1 comes back down the white navigation backgrouns slide up to hide and shows white text.
Any help or tips to learn how to do this would be greatly appreciated! :-)
var lastScrollTop = 0;
$(window).on('scroll', function() {
var header = $('.header');
var stage0 = $('.stage-0');
var scrollTop = $(window).scrollTop();
if (scrollTop > lastScrollTop) {
// down scroll
if (scrollTop > stage0.offset().top + stage0.height()) {
header.addClass('hide');
}
} else {
// up scroll
if (scrollTop <= stage0.offset().top + stage0.height()) {
header.removeClass('headerBGchange headerLIchange');
} else {
header.removeClass('hide').addClass('headerBGchange headerLIchange BGupTranistion');
}
}
lastScrollTop = scrollTop;
});
.header {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
height: 80px;
-webkit-transition: top .5s ease;
transition: top .5s ease;
position: fixed;
width: 100%;
top: 0;
background-color: transparent;
overflow: hidden;
}
.header ul {
margin: 20px;
padding: 0;
}
.header ul li {
display: inline-block;
margin-right: 20px;
color: white;
}
.header ul li:last-child {
margin-right: 0;
}
.hide {
top: -80px;
}
.headerBGchange {
Background: white;
}
.BGupTranistion {
}
.header.headerLIchange ul li {
color: Blue;
}
.header.headerLIchange {
border-bottom: 1px solid black;
}'
</style>
<!--stage style--><style>
.stage {
color: #fff;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: center;
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center;
-webkit-box-align: center;
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
height: 100vh;
background-color: white;
border-bottom: 1px solid black;
font-size: 48px;
height: 200px;
width: 100%;
}
.stage-0 {
background: grey;
}
.stage-24 {
background: #433937;
}
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<div class="header">
<ul>
<li>Home</li>
<li>About</li>
<li>Contact</li>
</ul>
</div>
<div class="stage stage-0">1</div>
<div class="stage stage-2">3</div>
<div class="stage stage-4">5</div>
<div class="stage stage-6">7</div>
<div class="stage stage-8">9</div>
<div class="stage stage-10">11</div>
<div class="stage stage-12">13</div>
<div class="stage stage-14">15</div>
<div class="stage stage-16">17</div>
<div class="stage stage-18">19</div>
<div class="stage stage-20">21</div>
<div class="stage stage-22">23</div>
You will need to add another container to achieve the effect you're looking for. What you essentially want to have is a container at the top and another container which will fade in and out depending on your scroll behaviour. So how do you achieve that? Create a -Element on top of the page, like your gray box is there at the moment. When scrolling down, do not transform it, instead, fade in another previously hidden container to act as your navigation when not at the top of the page. Now if you scroll back up, check the scroll location, and if the two locations of both containers overlap, start fading out the container you use when not at the top of the page. I do not think there is another solution. I might try and write a codepen on it now, I will edit my post if I had success. You could also try working it out with another div inside the actual header and z-index, though that might turn out really bad.
I have done my best to achieve what you want. Here is the CodePen.
I used two different divs, one called .dynamic-header and one normal header, and I've added a function to detect jQuery In-Viewport.
$.fn.isOnScreen = function(){
var element = this.get(0);
var bounds = element.getBoundingClientRect();
return bounds.top < window.innerHeight && bounds.bottom > 0;
}
I hope this fits your needs. Also, I changed some CSS around, using the Top-Property for the transition. You can outsource all of that into CSS classes and use them instead, but I thought this was the simplest solution for demonstration purposes. Is this what you want?
Edit 1: You named bartaile.com as an example. I took a look at the effect they create and recreated it. What you have to do is basically create a structure like this:
<div class="header-bg"></div>
<div class="header-content">
<ul>
<li>YOUR HEADER</li>
</ul>
</div>
I made another CodePen for this.
The header-bg has a height of 0. The header-content has a height of, lets say, 80px, and a background-color of transparent. Now do NOT check which direction is scrolled. The only important aspect for the effect is, how far are you from the top / is a specific element in viewport? I went for 400px from top. Now when that requirement is met, just fade in the header-bg. It will be inbetween the wrapper and the content, and will provide a background. Together with that, you may also change the color of the header-content, but I did not do that. It is what bartaile.com does, tho, so you might want to include it. Enjoy!
Edit 2: I've edited the CodePen according to your comment. See it in action here. This does the following: A header is there. When scrolling down, it'll disappear. On scroll up, it'll bring up a background, but when scrolling so that scrollTop < 400, the background will fade out. As of what I understood, this is what you want. It uses the structure I posted above.
I check out "bartaile.com" and I have to point out that what they use is a third party lib called 'fullpage'.If you wanna achieve that kind of effect, you should check out this lib fullpage.js. This is a simple and easy to use plugin to create fullscreen scrolling websites (also known as single page websites or onepage sites). It allows the creation of fullscreen scrolling websites, as well as adding some landscape sliders inside the sections of the site.
This plugin can handle "full screen scrolling" and also normal scrolling. You can achieve your effect with this much more easier