Avoid container's overflow scrollbars with "enter from side" effect - javascript

I'm working on a one/single page scroll website. I have a couple of sections each one containing 2 columns and I'm trying to make them to enter from the left/right with a fade effect. I'm using CSS transforms and jquery to activate the effect only when the user scrolls and reachs its corresponding section. Here's an example:
http://jsfiddle.net/Rv35g/
(Resize your window so it fits the container's width)
HTML:
<div class="container animation-init">
<div class="left">Column 1</div>
<div class="right">Column 2</div>
</div>
CSS:
body, html{
margin: 0;
height: 100%;
}
.container{
width: 600px;
height: 100%;
margin: 0 auto;
background: green;
}
.container .left, .container .right{
width: 50%;
float: left;
color: white;
height: 100%;
}
.container .left{
background: red;
}
.container .right{
background: blue;
}
.container.animation-init .left, .container.animation-init .right{
opacity: 0;
}
.container.animation-init .left{
-webkit-transform: translate(-80px, 0);
-moz-transform: translate(-80px, 0);
transform: translate(-80px, 0);
}
.container.animation-init .right{
-webkit-transform: translate(80px, 0);
-moz-transform: translate(80px, 0);
transform: translate(80px, 0);
}
.container.animation-init.animation-ready .left, .container.animation-init.animation-ready .right{
opacity: 1;
-webkit-transition: 0.5s;
-moz-transition: 0.5s;
transition: 1s;
-webkit-transform: translate(0, 0);
-moz-transform: translate(0, 0);
transform: translate(0, 0);
}
JS:
$(function() {
$('.container').addClass('animation-ready');
});
The problem is that when my columns are on its initial position they generate horizontal scrollbars because they're going outside the container... Do you have any idea on how could I handle this? I can't use overflow: hidden; cause I'll be cutting part of the animation. I also tried to put overflow-x: hidden; to the html tag but since the effects only activate when you reach its corresponding section the overflow stills being a problem specially on mobile devices...
EDIT: The problem with overflow-x: hidden is that the extra space stills there, so when scrolling with your finger or mousewheel-click arrow function it's possible for you to end up in one of those blank spaces losing the center of the page. Also, in mobile devices, it takes this overflow as part of the general width, so If I have and element coming from -200px to the left, it'll show the container's width + the aditional 200. That's a problem, specially when it comes to the elements positioned at the bottom of the page, cause they're on their init position waiting for you to reach them to start the animation. In the example I posted the overflow disappears almost instantly cause the animation is being triggered automatically, but as I told you at the begining, I have multiple sections where the column's animation starts only if you reach their parent sections.

Related

Scrolling Text in Chrome Disappears after some time

I created a marquee-like effect on the top of this page. The text is coded to continuously scroll horizontally. The text should continuously scroll with no gaps. It's working in Safari and Firefox, but for some reason in Chrome, after a few seconds, it just cuts off. The weird thing is, if I highlight the area where I know the text is, it reappears. Do you all know why this is happening? Any insight/help would be appreciated as I am a student learning how to code! I've attached screenshots, of how it first looks when the text disappears, and the other screenshot shows it reappearing after I highlight the area.
Screenshot of Text Disappearing
Screenshot of me Highlighting the area of the scrollable text, makes the text visible again on the page
I am using MacOS Catalina Version 10.15.7 and my Chrome version is Version 87.0.4280.88 (Official Build) (x86_64). I showed this code to a friend as well, and they experienced the same issue in Chrome.
UPDATE: Looks like this issue is related to overflow:hidden
Below is my html
<section class="intro section section-pad bg-cover" id="intro">
<div class="copy container">
<div class="marquee">
<!-- Here we add the title in multiple repeating times using javascript -->
<span>Event -- January 1-2, 2020, Zoom</span>
</div>
</section>
Here is the CSS:
.section {
/*each section will take 100% of the height of browser */
min-height: 100vh;
/* Will help to vertically align container box */
display: flex;
position: relative;
}
/* Provide padding to left and right of section */
.section-pad {
padding-left: 5vw;
padding-right: 5vw;
}
.container {
/* Take the width of widest content box */
max-width: 780px;
/* Center our box horizontally and vertically using flex on .section */
margin: auto;
}
.marquee {
position: absolute;
top: 3vh;
left: 0;
width: 100%;
/*Each letter will be 5% of viewport width */
font-size: 5vw;
/* As tall as text */
line-height: 1;
text-transform: uppercase;
/*no scrollbars */
overflow: hidden;
}
.marquee span {
transform: translate3d(0, 0, 0);
-webkit-animation-name: moveLeft;
animation-name: moveLeft;
-webkit-animation-duration: 500s;
animation-duration: 500s;
-webkit-animation-timing-function: linear;
animation-timing-function: linear;
-webkit-animation-iteration-count: infinite;
animation-iteration-count: infinite;
/*This will ensure the text stays all on the same line */
white-space: nowrap;
/* Our span is inline by default, so change it to block */
display: block;
/*Help with animation */
position: relative;
}
#keyframes moveLeft {
0% {
/* transform: translate(0);*/
-webkit-transform: translatex(0);
transform: translatex(0);
}
100% {
/* transform: translateX(-3000vw); */
-webkit-transform: translatex(-3000vw);
transform: translatex(-3000vw);
}
}
#-webkit-keyframes moveLeft {
0% {
/* transform: translate(0);*/
-webkit-transform: translatex(0);
transform: translatex(0);
}
100% {
/* transform: translateX(-3000vw); */
-webkit-transform: translatex(-3000vw);
transform: translatex(-3000vw);
}
}
And Finally here is the Javascript used
function makeMarquee () {
const title ='Event -- January 1-2, 2021, Zoom'
//use Array constructor to create an empty list with a length of 50 that is filled with the title.
//We can join all the contents of array using dash
const marqueeText = new Array(500).fill(title).join(' -- ')
//query Selector same as $ jquery, grab the span tags
const marquee = document.querySelector('.marquee span')
//set the text of span to be the marqueeText
marquee.innerHTML = marqueeText
}
makeMarquee()
Below is a Snippet as well
function makeMarquee () {
const title ='Event -- January 1-2, 2021, Zoom'
//use Array constructor to create an empty list with a length of 50 that is filled with the title.
//We can join all the contents of array using dash
const marqueeText = new Array(500).fill(title).join(' -- ')
//query Selector same as $ jquery, grab the span tags
const marquee = document.querySelector('.marquee span')
//set the text of span to be the marqueeText
marquee.innerHTML = marqueeText
}
makeMarquee()
.section {
/*each section will take 100% of the height of browser */
min-height: 100vh;
/* Will help to vertically align container box */
display: flex;
position: relative;
}
/* Provide padding to left and right of section */
.section-pad {
padding-left: 5vw;
padding-right: 5vw;
}
.container {
/* Take the width of widest content box */
max-width: 780px;
/* Center our box horizontally and vertically using flex on .section */
margin: auto;
}
.marquee {
position: absolute;
top: 3vh;
left: 0;
width: 100%;
/*Each letter will be 5% of viewport width */
font-size: 5vw;
/* As tall as text */
line-height: 1;
text-transform: uppercase;
/*no scrollbars */
overflow: hidden;
}
.marquee span {
transform: translate3d(0, 0, 0);
-webkit-animation-name: moveLeft;
animation-name: moveLeft;
-webkit-animation-duration: 500s;
animation-duration: 500s;
-webkit-animation-timing-function: linear;
animation-timing-function: linear;
-webkit-animation-iteration-count: infinite;
animation-iteration-count: infinite;
/*This will ensure the text stays all on the same line */
white-space: nowrap;
/* Our span is inline by default, so change it to block */
display: block;
/*Help with animation */
position: relative;
}
#keyframes moveLeft {
0% {
/* transform: translate(0);*/
-webkit-transform: translatex(0);
transform: translatex(0);
}
100% {
/* transform: translateX(-3000vw); */
-webkit-transform: translatex(-3000vw);
transform: translatex(-3000vw);
}
}
#-webkit-keyframes moveLeft {
0% {
/* transform: translate(0);*/
-webkit-transform: translatex(0);
transform: translatex(0);
}
100% {
/* transform: translateX(-3000vw); */
-webkit-transform: translatex(-3000vw);
transform: translatex(-3000vw);
}
}
<section class="intro section section-pad bg-cover" id="intro">
<div class="copy container">
<div class="marquee">
<!-- Here we add the title in multiple repeating times using javascript -->
<span>Event -- January 1-2, 2020, Zoom</span>
</div>
</div>
</section>
The gap in Chrome (and Edge) is caused by setting overflow: hidden on the marquee. The browsers seem to sense that they have shown enough (I am not sure what enough means in this context as the max-width is set quite low at 768px) and that they must not show the overflow but they carry on with the animation so after 50 seconds it starts again from the beginning.
Why the other browsers (Firefox, Safari) don't honor the overflow I have not been able to discover.
If you change the .marquee to have overflow: visible then all these browsers will continue the animation with no gaps.
UPDATE: in addition section is given overflow: hidden and the timing and distance travelled has been altered to prevent an x-overflow bar showing.
function makeMarquee () {
const title ='Event -- January 1-2, 2021, Zoom'
//use Array constructor to create an empty list with a length of 50 that is filled with the title.
//We can join all the contents of array using dash
const marqueeText = new Array(500).fill(title).join(' -- ')
//query Selector same as $ jquery, grab the span tags
const marquee = document.querySelector('.marquee span');
//set the text of span to be the marqueeText
marquee.innerHTML = marqueeText
// setTimeout(function () {marquee.style.animationName = 'moveLeft';},1000);
}
makeMarquee()
.section {
/*each section will take 100% of the height of browser */
min-height: 100vh;
/* Will help to vertically align container box */
display: flex;
position: relative;
overflow: hidden; /* added to prevent 'gap' appearing on Chrome/Edge */
}
/* Provide padding to left and right of section */
.section-pad {
padding-left: 5vw;
padding-right: 5vw;
}
.container {
/* Take the width of widest content box */
max-width: 780px;
/* Center our box horizontally and vertically using flex on .section */
margin: auto;
}
.marquee {
position: absolute;
top: 3vh;
left: 0;
width: 100%;
/*Each letter will be 5% of viewport width */
font-size: 5vw;
/* As tall as text */
line-height: 1;
text-transform: uppercase;
/*no scrollbars */
/* but - make visible otherwise Chrome/Edge stop showing overflowed bits so get a gap */
overflow: visible; /* was hidden not visible */
}
.marquee span {
transform: translate3d(0, 0, 0);
animation-name: moveLeft;
animation-duration: 550s; /* altered from 50s as have longer for the text to travel now */
animation-timing-function: linear;
animation-iteration-count: infinite;
/*This will ensure the text stays all on the same line */
white-space: nowrap;
/* Our span is inline by default, so change it to block */
display: block;
/*Help with animation */
position: relative;
width: 4000vw; /* this is a bit hacky but does the trick - fools Chrome etc into thinking overflow is OK */
}
#keyframes moveLeft {
0% {
transform: translateX(0);
}
100% {
transform: translateX(-100%);/* was 3000vw */
}
}
<section class="intro section section-pad bg-cover" id="intro">
<div class="copy container">
<div class="marquee">
<!-- Here we add the title in multiple repeating times using javascript -->
<span>Event -- January 1-2, 2020, Zoom</span>
</div>
</div>
</section>

Is there any way to animate transform-origin in combination with transform: scale?

So I have an image viewer which has a zoom functionality, which works via the transform: scale() property.
Animating the zoom is no problem with transition: transform .3s.
To make the zoom on the mousewheel go to where the mousewheel is pointed, I calculated the correct position to set the new origin, but when I set it, it just jumps there with no animation.
What I have tried:
Setting transition for the transform-origin property → Doesn't work
Doing it manually in JS with setTimeout and slowly setting the transform-origin at the right position → plays the zoom animation and then jumps
Is there any way to animate both transform: scale() and transform-origin in one go?
Dupe
As the last question has been closed as a duplicate of How to have multiple CSS transitions on an element?, here is a snippet, to show you that this is not my question.
const img = document.querySelector('#container img');
let on = true;
const toggleEffect = () => {
if(on) {
img.style.transform = 'scale(2.5)';
img.style.transformOrigin = '80% 80%';
} else {
img.style.transform = 'scale(1.4)';
img.style.transformOrigin = '20% 20%';
}
on = !on;
};
#container {
width: 500px;
height: 300px;
overflow: hidden;
background-color: red;
}
#container img {
height: 100%;
width: 100%;
object-fit: contain;
transform: scale(1.4);
transform-origin: 20% 20%;
transition: transform .3s, transform-origin .3s;
}
<div id="container">
<img src="https://images.unsplash.com/photo-1482066490729-6f26115b60dc?ixlib=rb-1.2.1&auto=format&fit=crop&w=2004&q=80"/>
</div>
<button onclick="toggleEffect()">Toggle</button>
EDIT: Technically this is a duplicated. (Chrome Bug in some versions)
- Using both transition:
body, div {
width: 100%;
height: 100vh;
overflow: hidden;
}
div {
background-color: gray;
width: auto;
display: flex;
justify-content: center;
align-items: center;
font-size: 30px;
transform: scale(1.1);
transform-origin: 50% -30px -100px;
transition: transform-origin .2s ease-in-out, transform 4s ease-in-out;
}
div:hover {
transform: scale(1.7);
transform-origin: 100px 100px;
}
<div>Test</div>
- Using animation with#keyframes:
body,div {
width: 100%;
height: 100vh;
}
div {
width: auto;
display: flex;
justify-content: center;
align-items: center;
transform-origin: 0 0 0;
animation: scale-origin 3s infinite;
font-size: 30px;
}
#keyframes scale-origin {
0% {
transform: scale(.5);
transform-origin: 100px 100px 1000px;
}
100% {
transform: scale(1.1);
transform-origin: left 500px -30px
}
}
<div>Test</div>
For me the only way to get around this bug was to ensure a redraw of the element on each "animation" (in this case transition) frame as you can clearly see via getComputedStyle that the transform-origin is correctly transitioned!
Basically I added eventlisteners for the transitionstart and transitionend and on each animationframe toggle some style attribute that enforces a redraw (f.e. in my case margin-left from 0 to 1 to 0px until the animation is finished)
function forceRedraw(ts) {
this.style.marginLeft = this.style.marginLeft == '1px' ? '0px':'1px';
if (this.classList.contains('transitioning'))
requestAnimationFrame(forceRedraw.bind(this));
}
In my example I transition rotation and the transform-origin (from top left to bottom left) at the same time.
https://codepen.io/ftav/pen/QWvYEPj
Depending on which element you modify this might have more or less of a performance impact. It works fine for me. I just wish they would fix the bug and this workaround could go away.

Triangle/Slanted Menu Style?

I would like to create the following webpage, where the navigation bar drops down on and is slanted.
So when a user opens the website its front page looks like
]1
Then when a user presses the "menu button" (which I have not drawn), the following menu bar appears (ideally slides down as an animation)
I really need help with designing the slanted navigation bar and adding the subsequent animation.
Thanks!
You can use an SVG shape as a background, and really any shape you want to make.
CodePen Link with an animation as well
HTML:
<div class="triangle-container">
<svg height="300" width="500">
<polygon points="0,-200 500,-200 500,100" class="triangle" />
Sorry, your browser does not support inline SVG.
</svg>
</div>
CSS:
body{
}
.triangle-container{
width: 500px;
margin: auto;
text-align:center;
border: 1px solid white;
&:hover, &:active{
.triangle{
transform: translate(0px, 200px);
}
}
.triangle{
fill: black;
transition: all 0.8s ease-in-out;
#keyframes mymove {
0% {opacity:0}
50% {opacity:1}
100% {opacity:0}
}
transform-origin: 250px 250px;
}
}
One way of doing it is if you have a triangle image, with a height of 0. And all of your menu items are off the top of the screen, out of view. When you want the menu to slide down, use jquery animate to increase image height and slide all of the menu items down.
const time = 700;
$("#triangleId").animate({
height: "+=10px"
}, time);
$("#menuItemOneId, #menuItemTwoId...").animate({
top: "+=10px"
}, time);
I made a little way using clip-path and css keyframes. This way you can avoid javascript and the code is responsive no pixels needed.
HTML
<html>
<body>
<div class = 'navbar'></div>
</body>
</html>
CSS
.navbar{
width: 100vw;
height: 25vh;
background-color: red;
clip-path: polygon(100% 0, 100% 100%,0% 0%);
animation: open 3s infinite;
}
#keyframes open{
0% {clip-path:polygon(100% 0, 100% 0,100% 0);}
100% {clip-path:polygon(100% 0, 100% 100%,0% 0%);}
}
Link to code pen for this:
https://codepen.io/mfortunato/pen/jOWmXvL

Best way to make a 2 column layout that works with multiple resolutions?

I've asked this a couple times but seems like I didn't word it quite right so will try do better here,
I'm trying to make a 2 column layout in HTML, CSS, & Java, what I want is the text on the left to center in the middle of both columns once the resolution is too low (by this I mean the columns look great in 1920x width and 1600x width, but when it gets down to 1200x800 the text breaks past the height of the right image).
I've seen a website that once the page width hits a certain point (around 1200x width) the text in the left column snaps to center in the middle of both, which results in the page looking good at all res. I have a feeling the text is overlayed on top of both columns with a java snippet that tells the text to move into the center at a certain width, only problem is I don't know how to achieve that,
I've attached my code at the bottom but in my version the text is inside the left column, am I right thinking that the text is probably on-top of both columns? and is there a javascript to tell the text to move center at a certain width? would really appreciate any help!
HTML:
<div class="content1">
<div class="column1 animation fadeInUp">
<div class="title1">
<h3>STATEMENT</h3> .
<h2>Title of Some Sort.</h2>
<div class="blue-line"></div>
</div>
<p1>Paragraph text.<br></p1>
<button class="svg1">FORUM</button>
<button class="svg2">SIGN UP</button>
</div>
<div class="column2">
<div class="column2pic"></div>
</div>
</div>
CSS:
.content1 {
display: flex;
margin-left:100px;
margin-right:0px;
}
.column1 {
display:inline-block;
flex: 31%;
padding-bottom: 0px;
padding-right:50px;
opacity: 0; animation-play-state: paused;
}
.animated {
-webkit-animation-duration: 1.5s;
animation-duration: 1.5s;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
animation-play-state: running;
}
.fadeInUp {
-webkit-animation-name: fadeInUp;
animation-name: fadeInUp;
}
#keyframes fadeInUp {
from {
opacity: 0;
-webkit-transform: translate3d(0, 2.5rem, 0);
transform: translate3d(0, 2.5rem, 0);
}
to {
opacity: 1;
-webkit-transform: none;
transform: none;
}
.column2 {
flex: 50%;
padding-bottom: 0px;
padding-left:100px;
padding-top:0px;
width:50vw;
}
.column2pic {
background-image: linear-gradient(rgba(0, 0, 0, 0.3), rgba(0, 0, 0,
0.0)), url(../Assets/Images/Content1pic);
background-size:cover;
z-index: 100;
width:50vw;
height:600px;
}
NOTE: the animation is just a simple effect for the left text to fade up, but don't mind if anyone excludes that part to keep it simple.
Let me know if you have any ideas! Thanks!
You will need to use css #media. In your case, you will have to create #media only screen and (max-width: 1200px) with the style that you would like at this size. See below an example of it. I put the width to 400px to fit with this snippet. When you resize the browser window under 400px #media only screen and (max-width: 400px), it lowers the text size font-size: 20px; and align it in the center text-align: center;.
#mypic {
width: 100%;
max-width: 560px;
height: 350px;
background-image: url("https://images.pexels.com/photos/531880/pexels-photo-531880.jpeg?auto=compress&cs=tinysrgb&h=350");
font-size: 50px;
}
#media only screen and (max-width: 400px) {
#mypic {
font-size: 20px;
text-align: center;
}
}
<div id="mypic">My Title In Picture!</div>

possible to shrink contents of iframe?

Is there a way to shrink what's inside an iframe without adjusting css?
any magical 'zoom' parameter out there?!!!
I have a 600px preview iframe i want to fit a 1000px site in without scrollbars...
CSS3 can handle this. This bit of code should handle most all browsers or simply reduce it to fit your needs. No need to "adjust" any existing CSS:
iframe {
-moz-transform: scale(0.25, 0.25);
-webkit-transform: scale(0.25, 0.25);
-o-transform: scale(0.25, 0.25);
-ms-transform: scale(0.25, 0.25);
transform: scale(0.25, 0.25);
-moz-transform-origin: top left;
-webkit-transform-origin: top left;
-o-transform-origin: top left;
-ms-transform-origin: top left;
transform-origin: top left;
}
Or if you want inline style for example just firefox:
<style>
#IDNAME {
-moz-transform: scale(0.25, 0.25);
-moz-transform-origin: top left;
}
</style>
Then of course simply add the ID to your iframe:
<iframe id="IDNAME" src="http://www.whatever.com"></iframe>
You absolutely can do this, just fine.
Only caveat is you need to transform the iframe, and position it absolute:
iframe {
/* Set the width of the iframe the size you want to transform it FROM */
width: 1108px;
height: 710px;
/* apply the transform */
-webkit-transform:scale(0.25);
-moz-transform:scale(0.25);
-o-transform:scale(0.25);
transform:scale(0.25);
/* position it, as if it was the original size */
position: absolute;
left: -400px;
top: -200px;
}
To see an example look at: http://jsfiddle.net/8DVNa/
If you control the Iframe-content, you might find this little hack of mine useful: http://futtta.be/squeezeFrame/
It's a cross-browser standalone javascript thingy that tries to automatically adjust the size of the page it's called from to the available size of the Iframe using css zoom and moz-transform.
I have several shopping sites that I have ported to my new site and
after fixing the view/vantage point of focus heres what I got...
the site fit nicely inside my iframe per page... the font size difference
is better than the focus issue...
I guess it was a good trade off
#wrap {
width: 115%;
height: 2000px;
padding: 0;
overflow: hidden;
}
#frame {
-ms-zoom: 0.5;
-ms-transform-origin: 0 0;
-moz-transform: scale(0.75);
-moz-transform-origin: 0px 75px;
-o-transform: scale(0.75);
-o-transform-origin: 0px 75px;
-webkit-transform: scale(0.75);
-webkit-transform-origin: 0 0;
}
#frame {
width: 115%;
height: 2000px;
overflow: hidden;
}
<div id="wrap">
<iframe id="frame" src="http://hempseedoilsoap.com/" scrolling="auto" align="center"></iframe>
</div>
Well, in short no.
You can use in-line CSS to set the width/height to 600px and then also set the overflow:hidden
I'm afraid not. Your only option would be to use site-specific CSS modifiers to reduce font and element size.

Categories

Resources