How can I make scroll lock? - javascript

I just want to make a website like tesla.com and I saw in source scroll bar lock I have a html code:
<div id="cont-1" class="full-container">
<p> This is container 1 </p>
</div>
<div id="cont-2" class="full-container">
<p> This is container 2 </p>
</div>
<div id="cont-3" class="full-container">
<p> This is container 3 </p>
</div>
and style.css
.full-container { width: 100%; height: 100vh; }
I want to make in here when I'm scrolling down or up scroll is should be locked in cont-3 or cont-2 how can I make this?
Sample website: https://www.tesla.com/

You should look into the newer CSS property scroll-snap. Without this it's going to be a good chunk of JS scripting.
.container {
display: flex;
overflow: auto;
outline: 1px dashed lightgray;
flex: none;
width: 256px;
height: 256px;
flex-flow: column nowrap;
scroll-snap-type: y mandatory;
}
.container > div {
text-align: center;
scroll-snap-align: center;
flex: none;
line-height: 256px;
font-size: 128px;
width: 256px;
height: 100%;
}
.container > div:nth-child(even) {
background-color: #87EA87;
}
.container > div:nth-child(odd) {
background-color: #87CCEA;
}
<div class="container y proximity-scroll-snapping" dir="ltr">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
</div>

you can do this simply by using the fullpage.js library in javascript
This definitely helps you
See the below demo link:
https://alvarotrigo.com/fullPage/examples/scrollBar.html

That's a scroll-snap.
If you don't particularly care about IE11 support, you can try this
html {
scroll-snap-type: y mandatory;
}
/* your element */
.full-container {
height: 100vh;
width: 100vw;
scroll-snap-align: start;
}
See here for the complete reference.
You can also use a JS library like scroll-snap (but I prefer the CSS one personally)

Related

Parent component not resizing to fit children

I have a <div className="canvas"> element that contains four <div className="stripe stripe-color"> elements that I will be styling dynamically adding random color classes.
I want to use this canvas element as a 'dynamic background'.
As you can see, I have a <div className="children">{props.children}</div> element among the <div className="stripe"/> elements:
const Canvas = (props) => {
return (
<div className="stripe-container">
<div className="children">{props.children}</div>
<div className="stripe stripe-yellow" />
<div className="stripe stripe-green" />
<div className="stripe stripe-red" />
<div className="stripe stripe-purple" />
</div>
);
};
And SCSS:
.stripe-container {
display: grid;
grid-template-columns: repeat(4, 1fr);
padding: 0;
margin: 3vw;
height: 100vh;
}
.children {
position: absolute;
width: calc(100% - 6vw);
}
.stripe-yellow {
background: #fdc111;
}
.stripe-green {
background: #00ad5e;
}
.stripe-red {
background: #d33136;
}
.stripe-purple {
background: #8f3192;
}
The problem here is that <div className="canvas"> won't grow to fit the children's height so if the content in <div className="children">{props.children}</div> becomes too large or if the user uses a smaller viewport, the children will overflow into the height and allow you to scroll, but canvas won't expand to fit it's children.
As additional information, props.children is a React component that contains a list of "card elements" for a restaurant's menu. The cards and its container use flex to wrap around if they don't have enough space horizontally. This is causing the canvas to become too small on smaller viewports. height:100% and their variants won't work either.
Any ideas into how I can get the desired behavior? I'm also open to refactoring as long as my requirement of achieving dynamic color stripes remains.
Here's a minima reproducible example without React:
.stripe-container {
display: grid;
grid-template-columns: repeat(4, 1fr);
padding: 0;
margin: 3vw;
height: 100vh;
}
.children {
position: absolute;
width: calc(100% - 6vw);
}
.stripe {
height: 100%
}
.stripe-yellow {
background: #fdc111;
}
.stripe-green {
background: #00ad5e;
}
.stripe-red {
background: #d33136;
}
.stripe-purple {
background: #8f3192;
}
.child-container {
display: flex;
flex-wrap: wrap;
}
.child {
border: 1px solid white;
margin: 1rem;
width: 25vw;
height: 25vw;
background: lightgray;
opacity: 80%;
}
<div class="stripe-container">
<div class="children">
<div class="child-container">
<div class="child">one</div>
<div class="child">two</div>
<div class="child">three</div>
<div class="child">four</div>
<div class="child">five</div>
<div class="child">six</div>
<div class="child">seven</div>
<div class="child">eight</div>
<div class="child">nine</div>
</div>
</div>
<div class="stripe stripe-yellow"></div>
<div class="stripe stripe-red"></div>
<div class="stripe stripe-green"></div>
<div class="stripe stripe-purple"></div>
</div>
I'm not sure I understand 100% what you're trying to achieve. But I'll try my best to help you.
Removing the absolute from the children and putting it on the stripes instead might do the trick. Additionally, you'll want to position the stripes on 25% of the width to the left respectively.
I don't think you need CSS grid for this anymore, so I removed it and added some small tweaks as well. Let me know if you have any questions or if I got the question wrong.
.stripe-container {
padding: 0;
margin: 3vw;
position: relative;
}
.children {
position: relative;
z-index: 2;
width: 100%;
}
.stripe {
width: 25%;
height: 100%;
position: absolute;
top: 0;
bottom: 0;
z-index: 1;
}
.stripe-yellow {
left: 0;
background: #fdc111;
}
.stripe-green {
left: 25%;
background: #00ad5e;
}
.stripe-red {
left: 50%;
background: #d33136;
}
.stripe-purple {
left: 75%;
background: #8f3192;
}
.child-container {
display: flex;
flex-wrap: wrap;
}
.child {
border: 1px solid white;
margin: 1rem;
width: 25vw;
height: 25vw;
background: lightgray;
opacity: 80%;
box-sizing: border-box;
}
<div class="stripe-container">
<div class="children">
<div class="child-container">
<div class="child">one</div>
<div class="child">two</div>
<div class="child">three</div>
<div class="child">four</div>
<div class="child">five</div>
<div class="child">six</div>
<div class="child">seven</div>
<div class="child">eight</div>
<div class="child">nine</div>
</div>
</div>
<div class="stripe stripe-yellow"></div>
<div class="stripe stripe-red"></div>
<div class="stripe stripe-green"></div>
<div class="stripe stripe-purple"></div>
</div>
This way, the stripes work as a background for the stripe-container no matter the size, and since the children element is no longer absolute, the container is finally able to have the same size as the children.
Why not use a linear gradient for the striped background? You could accomplish what you're trying to do with simpler CSS and without the extraneous markup.
Optional: If you declared custom properties for the stripe colors you could change them simply by setting different values instead of having to rewrite the gradient each time (although the gradient itself isn't complicated or particularly verbose anyway.)
:root {
/*
Using custom properties here to demonstrate
that you could control the stripe colors without
hard-coding them in the stylesheet. an element
could declare its own colors via another class
or even an inline style, e.g.
<div style="--stripe-1: blue">
This isn't required. Just a suggestion.
*/
--stripe-1: #fdc111; /* yellow */
--stripe-2: #00ad5e; /* green */
--stripe-3: #d33136; /* red */
--stripe-4: #8f3192; /* purple */
}
.container {
padding: 0;
min-height: 100vh;
display: flex;
flex-wrap: wrap;
background: linear-gradient(
to right,
var(--stripe-1) 0 25%,
var(--stripe-2) 25% 50%,
var(--stripe-3) 50% 75%,
var(--stripe-4) 75%
);
}
.container > * {
border: 1px solid white;
margin: 1rem;
width: 25vw;
height: 25vw;
background: lightgray;
opacity: 80%;
}
<div class="container">
<div>one</div>
<div>two</div>
<div>three</div>
<div>four</div>
<div>five</div>
<div>six</div>
<div>seven</div>
<div>eight</div>
<div>nine</div>
</div>

How to make columns the same height dynamically?

I am having trouble making my columns the same height. I would simply like to make the columns the same height. Here is my code:
HTML:
<main>
<div id="left-column">
<div id="facets"></div>
</div>
<div id="right-column">
<div id="stats"></div>
<div id="hits"></div>
<div id="pagination"></div>
</div>
</main>
CSS:
#left-column {
float: left;
width: 25%;
background-color: #fff;
border-right: 1px solid #cdcdcd;
}
#right-column {
width: 75%;
margin-left: 25%;
}
The issue I'm having is that because the id's of each of the divs dynamically generate content, the heights of each columns will be based on what are inside those divs. Is there any way to set the column to the height of whatever is longer than the other column? Or is there a way to set the column height to something fixed? I have tried to add height: 1000px for each of the ids but that doesn't even seem to apply to the CSS. Any help would be appreciated.
There are two big options: Use Javascript, or don't use Javascript.
If you use Javascript, assuming you use a library which helps certain portions of your code become cross-browser without a lot of work on your part, then it's almost guaranteed to work on any browser that supports it.
Big Fall Back: If someone has Javascript disabled it doesn't look good.
Not Javascript
Recently CSS has gotten a new display type, flex. Now, it should be said, based on Can I Use, IE 11 has messed up support for flexbox, but a majority of browsers support it (85% support it without prefixes, and that includes most mobile browsers too!)
.flex-container {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}
#left-column {
-webkit-box-flex: 0;
-webkit-flex: 0 0 25%;
-ms-flex: 0 0 25%;
flex: 0 0 25%;
border-right: 1px solid #CDCDCD;
}
#right-column {
-webkit-box-flex: 1;
-webkit-flex: 1 1;
-ms-flex: 1 1;
flex: 1 1;
padding-left: 5px;
}
<main class="flex-container">
<div id="left-column">
<div id="facets">test</div>
</div>
<div id="right-column">
<div id="stats" test></div>
<div id="hits">test</div>
<div id="pagination">test</div>
</div>
</main>
Via CSS and to include older browsers like IE8 you have display:table/table-cell.
main {
display: table;
table-layout: fixed;
width: 100%;
}
#left-column {
display: table-cell;
width: 25%;
background-color: #fff;
border-right: solid ;
}
#right-column {
display: table-cell;
width: 75%;
}
<main>
<div id="left-column">
<div id="facets">facets</div>
</div>
<div id="right-column">
<div id="stats">stats</div>
<div id="hits">hits</div>
<div id="pagination">pagination</div>
</div>
</main>
To include very old browser, you may also see http://alistapart.com/article/fauxcolumns a very solid technics since you columns have fixed width
If you want to restrict the height of each column to a limit. you can use max-height and min-height rule. But if you want to do it using Javascript. Here is the algorithm assuming that you call this function after your columns have had their content data filled in
function setHeight() {
var leftCol = document.querySelector("#left-column");
var rightCol = document.querySelector("#right-column");
var largerHeight = Math.max(leftColHeight.getBoundingClientRect().height, rightColHeight.getBoundingClientRect().height);
leftCol.style.height = largerHeight + "px";
rightCol.style.height = largerHeight + "px";
}
you may try and check my code I have use display flex to do what you want done .. check this link https://jsfiddle.net/qpfrtqh2/1/
.parent{
display: flex;
}
You can get help by using this code.
You need to use flex css.
<ul class="list">
<li class="list__item"><!-- content --></li>
<li class="list__item"><!-- content --></li>
<!-- other items -->
</ul>
and css as like below.
.list
{
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
}
.list__item
{
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}
You need some javascript code for fallback of flex css.
Try this (I added some background-colors just to see result)
main{ overflow: hidden;
}
#left-column {
float: left;
width: 25%;
background-color: red;
border-right: 1px solid #cdcdcd;
margin-bottom: -99999px;
padding-bottom: 99999px;
}
#right-column {
background-color: green;
width: 75%;
margin-left: 25%;
margin-bottom: -99999px;
padding-bottom: 99999px;
}
<main>
<div id="left-column">
<div id="facets">aa</div>
</div>
<div id="right-column">
<div id="stats">bb</div>
<div id="hits">cc</div>
<div id="pagination"></div>
</div>
</main>
There is no need to use javascript for that.
Just leverage standard table display in CSS.
FIDDLE

How do I overlay a div on an empty div containing a background image?

I want the #intro div to appear on the .backgroundimg div. I tried various ways like using z-index, positioning but nothing worked. Please help me with a solution and explain how it works.
Html
<div class='backgroundimg'></div>
<div id='#intro'>
<p>
random content
</p>
</div>
css
.backgroundimg {
background-image: url("http://s9.postimg.org/7c2rqzb2n/homeback.jpg");
height: 400px;
width:100%;
background-size:cover;
}
you want something like this ?? If yes, I will explain it in comment section :)
.backgroundimg {
position: relative;
background-image: url("http://s9.postimg.org/7c2rqzb2n/homeback.jpg");
height: 400px;
width: 100%;
background-size: cover;
display: table;
}
#intro {
positon: absolute;
display: table-cell;
vertical-align: middle;
text-align: center;
}
p {
color: yellow;
font-size: 50px;
}
<div class='backgroundimg'>
<div id='intro'>
<p>
random content
</p>
</div>
</div>

With jQuery how can you make all of the parent divs and body expand in height to accommodate content?

Objective
To have the page the page on my website to expand in height according to the dynamic data pushed into the container.
Background
The page has a set of images and text that is populated via a JSON feed. The text is overflowing into the footer because it is not expanding its containing div which would subsequently expand its containing div which would subsequently expand the body. So I need for a specific child div to push its multiple parent divs.
I have searched similar problems on Stackoverflow and attempted various CSS solutions such as giving all of the parent divs a CSS rule of clear:both or even in the HTML inserting a <div style="clear:both"></div> but none of those solutions worked.
So now I am experimenting with jQuery to see if I could find a solution to this problem.
I know I need to create a variable of some sort like
var newHeight = $("#carousel").height();
And that it needs to have push out the height with something like
$(".case").height(newHeight);
This is my current HTML
<body>
<div class="container">
<div class="block push">
<div id="mainContent" class="row">
<div class="large-12 columns">
<h1>Before & After Case Gallery</h1>
<div id="casesContainer">
<div id="carousel"></div>
</div>
<script id="casestpl" type="text/template">
{{#cases}}
<div class="case">
<div class="gallery_images_container">
<div class="item_container">
<div class="gallery_heading">BEFORE</div>
<img src="/assets/img/content/images-bruxzir-zirconia-dental-crown/cases/{{image}}_b_300.jpg" alt="Photo of {{alt}}" />
</div>
<div class="item_container">
<div class="gallery_heading">AFTER</div>
<img src="/assets/img/content/images-bruxzir-zirconia-dental-crown/cases/{{image}}_a_300.jpg" alt="Photo of {{alt}}" />
</div>
</div>
<div class="description_container">
<p>
<span><strong>Case Number {{{number}}} {{version}}:</strong></span>
{{{description}}}
</p>
</div>
</div>
{{/cases}}
</script>
The {{{description}}} in the <p> is overflowing into its parent divs <div class="description_container"> then <div class="case"> then <div id="carousel"> then <div class="casesContainer"> then <div class="large-12"> (which is a container in Foundation) then <div class="mainContent"> and so on.
Here is my CSS
html, body { height: 100%; }
.container { display: table; height: 100%; width: 100%; margin: 0 auto; }
.block { display: table-row; height: 1px; }
.push { height: auto; }
#mainContent {}
#casesContainer {
min-width:310px;
}
.image-navigation {
background: rgb(6,6,6);
color: #fff;
width:100%;
max-width: 640px;
height: 24px;
}
.image-navigation a {
color: #fff;
padding: 6px;
}
.image-navigation-previous, .image-navigation-next{
float:left;
width: 50%;
}
.image-navigation-previous {
text-align: right;
}
.image-navigation-next {
text-align: left;
}
#carousel {
height:auto;
min-height:600px;
overflow-y: auto;
}
.case {
max-width: 640px;
height:auto;
}
.gallery_images_container {
clear: both !important;
}
.item_container{
max-width: 320px;
float: left;
}
.gallery_heading {
background: black;
color: white;
width: 100%;
text-align: center;
}
.description_container {
background: none repeat scroll 0% 0% white;
min-width: 308px;
max-width: 640px;
padding: 6px 6px 12px 6px;
clear: both !important;
}
I realize that #carousel { height:auto; min-height:600px; overflow-y: auto; } is an ugly hack. It was just an experiment.
I hope that I am just completely missing something and this is an easy jQuery fix. Or maybe my HTML and CSS could use a different structure?
Not a complete fix but maybe helpful.
I've used this function but Internet Explore increases the heights on resize.
$(document).on('ready', function() {
// $(window).on('resize', function() {
var height1 = $("#r1c1").height();
if (height1 < $("#r1c2").height()) { height1 = $("#r1c2").height() }
if (height1 < $("#r1c3").height()) { height1 = $("#r1c3").height() }
$("#r1c1").height(height1);
$("#r1c2").height(height1);
$("#r1c3").height(height1);
// }).trigger('resize'); // Trigger resize handlers not working correctly with IE8.
});//ready

how to set the width of page element in jquery

there is a tool bar in the left of my page, the width of the tool bar is 35px, the main content panel is in the right of my page and has CSS float:right I want to set the width of main content panel with 100%-35px, so that the tool bar can be displayed, how can I achieve this effect, many thanks.
You can use calc(). But i'm not sure about browser compatibility. So try jquery solution.
Layout should be like this.
<div style="width: 100%">
<div id="toolbar" style="display: inline-block; width: 35px"></div>
<div id="main-content" style="display: inline-block"></div>
<div>
in jquery:
$("#main-content").width($(window).width() - 35);
if there is padding or margin detect them also.
It's convenient to do this by using absolute position. It doesn't need to use javaScript and it handle screen size change event correctly.
the css like bellow:
.toolbar {
position: absolute;
width: 35px;
}
.content {
position: absolute;
left: 35px;
right: 0px;
}
see the demo in jsFiddle.
Pure CSS based approach:
css:
.container {
padding-left: 50px;
border: 1px solid red;
}
.toolbar {
width: 35px;
margin-left: -50px;
padding: 0 5px;
list-style-type: none;
}
.main {
width: 100%;
}
.col {
display: inline-block;
vertical-align: top;
}
html:
<div class="container">
<ul class="toolbar col">
<li>Link1</li>
<li>Link2</li>
<li>Link3</li>
</ul>
<div class="main col">
<p>This is the place holder for Main Content</p>
</div>
</div>
http://cdpn.io/hlfFG
Sounds like this can easily be done with CSS.
#main-content {
width: 100%;
margin-right: 35px;
}

Categories

Resources