I have a website that basically has 2 pages. In total, there is 3 sections, with the first page showing the left and the middle, and the second showing the middle and the right. I'm wondering if there is a simple way to transition horizontally between the 2 pages. It would look something like this with the transition:
An extra problem comes when you need to resize the window. In that case, section A and C should get bigger and the transition should change accordingly while B is fixed width.
I think the best way is to create a single page because the loading breaks the immersion, but if it is simpler to create 2 pages because of the responsive web design then its fine. The easiest way I could think of is to move the user camera sideways, but the responsive web design complicates it.
Once we know the width of B we can set the whole thing up to be in columns.
This snippet uses grid to do this with the first and third items taking up any remaining space in the viewport.
By using CSS calc to ascertain the amount that has to be translated to move back and forth the whole thing is responsive and will adjust to different viewport/device widths.
* {
margin: 0;
}
body {
overflow: hidden;
}
button {
position: fixed;
z-index: 1;
}
.container {
/* set the width of the second item */
--bW: 200px;
width: calc(2 * (100vw - var(--bW)) + var(--bW));
height: 100vh;
display: grid;
grid-template-columns: 1fr var(--bW) 1fr;
transform: translateX(0);
transition: transform 1s ease;
overflow: hidden;
}
.slid {
transform: translateX(calc(-100vw + var(--bW)));
}
.container>* {
height: 100%;
display: inline-block;
}
.container> :nth-child(1) {
background: magenta;
}
.container> :nth-child(2) {
background: purple;
}
.container> :nth-child(3) {
background: teal;
}
<button onclick="document.querySelector('.container').classList.toggle('slid');">CLICK ME TO SLIDE</button>
<div class="container">
<div></div>
<div></div>
<div></div>
</div>
Related
I have a div which contains three more divs. The first one is a toolbar that can be collapsed (red in the example). It has a fixed height. The second one (black) has to fill all the remaining space, and must expand if the red one is collapsed. The third one (green) is in fact a button attached to the bottom of the red div. When the user clicks on it, it collapses or expands the red div.
<div id="container">
<div id="tools">
</div>
<div id="hider">
</div>
<div id="work-area">
</div>
</div>
I made an example on jsfiddle : https://jsfiddle.net/gpoa8s92/3/
I don't see how to make the black div take all the remaining space. I tried using a flexbox, and it works, but the green div isn't attached to the bottom of the red div anymore.
Is there a solution using ass less javascript as possible ?
Thank you !
I think your solution can be achieved with flexbox, just put tools and work area as siblings and for first set static height, flex-grow: 0 and flex shrink: 0, and for work area set height: 100%, flex-grow: 1 and flex shrink: 1.
This will make tools to occupy 100px and work area remaining place.
Since the toggle button is part of tools you can put it inside it, and move it outside using position: absolute and top: 100%, and give tools position: relative to stick toggle button to its bottom.
Now you can create a class for tools that set its height: 0 and animate it with CSS transitions.
Then on toggle button click, you can toggle a class on tools and it should be as you wanted.
Toggling tools height could be done without javascript- it would be a bit confusing but more accessible, here's an example of that: https://codepen.io/morganfeeney/pen/KiBty
Prepared an example for you - I've used BEM methodology for naming elements and cached used elements as variables.
const $toggleButton = $('.js-tools-toggle');
const $toggleContent = $('.js-tools-root');
const collapsedClass = 'tools--collapsed';
$toggleButton.on('click', function() {
$toggleContent.toggleClass(collapsedClass);
})
.container {
display: flex;
flex-direction: column;
height: 400px;
background-color: blue;
}
.tools {
transition: height 250ms ease-in-out;
position: relative;
display: flex;
flex-direction: column;
height: 100px;
}
.tools--collapsed {
height: 0px;
}
.tools__content {
height: 100%;
background-color: green;
overflow: hidden;
}
.tools__action {
position: absolute;
top: 100%;
left: 50%;
transform: translateX(-50%);
height: 20px;
background-color: red;
}
.work-area {
background-color: black;
flex: 1 1 auto;
height: 100%;
color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="tools js-tools-root">
<div class="tools__content"> Content of tools</div>
<div class="tools__action js-tools-toggle">
toggle
</div>
</div>
<div class="work-area">
content of work area
</div>
</div>
My hidden nav, which should stay under the main section, spills out when scrolling further down the page.
I have set my main section to min-height: 100vh with a background color and a z-index so I don't understand why this is still spilling out.
nav {
position: fixed;
top: 0;
right: 0;
width: 300px;
height: 100%;
background-color: #ff5000;
color: #fbf9f9;
font-family: "Anx Regular";
font-size: 28px;
display: flex;
flex-direction: column;
justify-content: center;
}
main {
position: relative;
z-index: 1;
background-color: #fbf9f9;
min-height: 100vh;
transition: transform 0.8s;
}
main.open {
transform: translate(-300px, 0);
}
const toggleTag = document.querySelector("a.toggle-nav")
const mainTag = document.querySelector("main")
toggleTag.addEventListener("click", function() {
mainTag.classList.toggle("open")
if (mainTag.classList.contains("open")) {
toggleTag.innerHTML = `<img src="close.svg">`
toggleTag.style.width = "30px"
} else {
toggleTag.innerHTML = `<img src="menu.svg">`
toggleTag.style.width = "30px"
}
https://anx.superhi.com/workshops.html
It's because of the <section class="crit1"> tag in <main> that has the css height: 100vh. This appears to be shortening that section. I don't know where else this is used, but just removing that rule fixes it. You could probably also do something more specific like section.crit1, section.crit1 section { height: auto; } if that rule is important elsewhere.
100vh means the full height of the window where it is displaying (say 800px, for example) so it's not what you need yo solve your problem. You set a position: fixed to the nav so it's always in the upper right corner of the screen even if you scroll down. If you need it to show just when you are at the top of the page, try switching to position absolute.
I had the same problem doing a task for freecodecamp.
I put both nav and main positions to absolute in CSS.
It stopped the overflow. Dunno if it will create problems down the road though.
I'm not sure if this is really solvable/possible but...
I'm trying to implement a particular animation where my screen is divided in 2 vertically on the first page, but after doing some sort of event (wheel, scroll, click, etc), the layout will animate smoothly to divide the screen horizontally.
If you hover over the first example, I tried to just rotate both inner elements, and then tried to resize the elements based on the new, rotated position. This did not work well.
As you can see, as the elements rotate, there are several issues:
They don't rotate perfectly in sync
You can see the ugly whitespace of the container behind it as it rotates
After rotating, the elements do not fill the container perfectly
I have tried many different things, like using z-index, absolute positioning, tried putting the inner elements in another nested container and then rotating the container, then adding height and width, but again the sizes didn't fit the container. I cannot seem to figure out how to make this work (without Javscript, if possible).
Essentially, the animation I have in mind would make the transition from the Initial Stage to the Final Stage seamless (ie. You wouldn't be able to see the whitespace in the background of the container, and the starting vertical line of separation would just slowly rotate to a horizontal line, while changing the position of the inner elements)
I hope this makes sense? I've been trying to get this animation to work for days...and I am exhausted of options/not creative enough/don't have the knowledge I need; help would be greatly appreciated.
.container {
display: flex;
border: 1px solid black;
width: 425px;
height: 500px;
margin: 5% auto;
}
.container:hover .left {
transform-origin: 100% 50%;
transform: rotate(90deg);
width: 100%;
}
.container:hover .right {
transform-origin: 0 50%;
transform: rotate(90deg);
width: 100%;
}
.left {
background-color: purple;
height: 100%;
width: 50%;
transition: all 2s;
}
.right {
background-color: yellow;
height: 100%;
width: 50%;
transition: all 2s;
}
.container2 {
display: flex;
flex-direction: column;
border: 1px solid black;
width: 425px;
height: 500px;
margin: 5% auto;
}
.left2 {
background-color: purple;
height: 50%;
width: 100%;
}
.right2 {
background-color: yellow;
height: 50%;
width: 100%;
}
Initial Stage
<p>(width of the container is the viewport; I don't care about if the element extends outside of the viewport during the transtion, but at the final stage, the element must be within it's container perfectly)</p>
<div class="container">
<div class="left"></div>
<div class="right"></div>
</div>
Final Stage
<p>(width of the container is the viewport; I don't care about if the element extends outside of the viewport during the transtion, but at the final stage, the element must be within it's container perfectly)</p>
<div class="container2">
<div class="left2">
I have content in here that I need fit within this container
</div>
<div class="right2">
I have content in here that I need fit within this container
</div>
</div>
Instead of adding transition to left/ right divs add it to the container div
.container {
display: flex;
border: 1px solid black;
width: 425px;
height: 500px;
margin: 5% auto;
transition: all 2s;
transform: rotate(0deg);
}
.container:hover {
transform: rotate(90deg);
width: 100%;
}
Also Remove transitions and transforms from left right divs
I'm trying to replicate the menu design used by:
https://www.pandaexpress.com/menu/appetizers
I think I am at the point where I need to use javascript/jquery, but I'm very new and unsure of my next step. When the user hovers over an image the image seems to slide into focus and display information below. I have tried to isolate this into separate actions, modeled by the following jfiddles:
https://jsfiddle.net/Lrqu8L0q/3/ (enlarges and focuses image on hover)
https://jsfiddle.net/4ud7wnop/1/ (slides down to reveal text on hover)
I tried combining them but when I add the
<p>This text is displayed on a downward slide after hover</p>
to the first jfiddle the paragraph isn't hidden.
Now I'm having trouble trying to think of a way to combine the both. I think I need to use javascript/jquery to create a function that applies the slide down to reveal text after the image enlarge has been completed. I'm very new to web design as a whole and am especially shaky with javascript and jquery.
I was wondering if I could write a function that checks if the image has expanded on enlarge yet, and after it's reached a desired height/width run the text slide function. Really not sure how to do this.. could someone point me in the correct direction?
I merged them together here: https://jsfiddle.net/danbovey/53ya31gm/
The main problem was, you need the image to be larger to cover over any detail text you may have.
I have commented on most changes I added in the fiddle. But here's the key parts:
I renamed the bg element to tile, it seemed more appropriate. Instead of working with height for the .slide-down class, I created a transform on the details div when the tile is hovered.
.tile:hover .details {
transform: translateY(150%);
}
You can learn about CSS transforms here: http://css3.bradshawenterprises.com/transforms/
The percentage of the transform can be calculated as the height of img / height of details - 300px / 200px = 150%
To create the growing effect, a pseudo :before element adds a white area the same size of the image before the tile, and when hovered, grows to 25px around each edge. And an identical element is added to the details div.
.tile:before {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #FFF;
transition: all 0.4s ease;
content: '';
}
.tile:hover:before {
top: -25px;
left: -25px;
width: calc(100% + 50px);
height: calc(100% + 50px);
}
Is this what you want here?
https://jsfiddle.net/Lrqu8L0q/9/
.thumbnail{
width: 100px;
height: 100px;
display:block;
z-index:999;
cursor: pointer;
-webkit-transition-property: all;
-webkit-transition-duration: 0.3s;
-webkit-transition-timing-function: ease;
margin: 0 auto;
position: relative;
top: 50%;
transform: translateY(-50%);
border-radius: 2px;
}
.bg:hover {
transform: scale(1.25)
}
.bg{
width: 150px;
height: 110px;
background-color: teal;
border-radius: 2px;
}
.slide-down {
border-radius: 3px;
height: 60px;
width: 150px;
position: relative;
transition: height 0.3s;
-webkit-transition: height 0.3s;
text-align: center;
overflow: hidden;
background-color: teal;
}
.bg:hover .slide-down {
height: 140px;
}
.container{
position: relative;
left: 150px;
top: 50px;
}
<div class="container">
<div class="bg">
<img src="https://static.pexels.com/photos/70497/pexels-photo-70497.jpeg" class="thumbnail"/>
<div class="slide-down">
<h2>Title</h2>
<p>This text is displayed after a downward slide on hover</p>
</div>
</div>
</div>
Basically what you need to do is put both your requirement into 1 combined object (in this I mean put both the Image & Text inside 1 container) like in the above example
<div class="bg">
<img src="https://static.pexels.com/photos/70497/pexels-photo-70497.jpeg" class="thumbnail"/>
<div class="slide-down">
<h2>Title</h2>
<p>This text is displayed after a downward slide on hover</p>
</div>
</div>
Both of them are put inside 1 container with class .bg, then what you want is to hover the container (not the thumbnail or description itself) and trigger both the scaling & slide-down the menu detail, you can do this by adding the CSS
.bg:hover { ... }
For the scaling, you need to put it together with the container so all the elements inside will be scaled to, then for the description inside it, you need to use
.bg:hover slide-down { ... }
This is where you set the animation that will expand the description of the menu (for explanation, this CSS will trigger on .bg hover, and applied to the element .slide-down inside of it)
So if I want to have two divs, each of 100% of the entire page, side by side, given that the wrapper has overflow:hidden, how should I go about implementing it?
I have tried using inline-block but it did not work.
I have tried using float too but it caused errors.
I want the second div to be hidden so I can change it's left as an animation, sort of like a slide.
Thanks in advance!
If I've understood you correctly, you can achieve what you're after using inline-block. You just have to be a little careful with white space (i.e. you need to make sure you've got no white space between the two child div elements). I've stopped the divs from wrapping by setting white-space: nowrap;.
<div class="foo">
<div> woo woo !</div><div> woo woo !</div>
</div>
.foo {
overflow: hidden;
white-space: nowrap;
}
.foo > div {
display: inline-block;
vertical-align: top;
width: 100%;
background: aqua;
}
.foo > div + div {
background: lime;
}
Try it out at http://jsfiddle.net/8Q3pS/2/.
Edit: Here's an alternative implementation using position: absolute;: http://jsfiddle.net/8Q3pS/5/. That way you'll be able to animate the second one into view using left. Note that you'll need to set a height on the parent div.
.foo {
position: relative;
width: 100%;
height: 1.5em;
overflow: hidden;
}
.foo > div {
position: absolute;
top: 0;
left: 0;
width: 100%;
background: aqua;
}
.foo > div + div {
left: 100%;
background: lime;
}
This should be purely a matter of positioning one of the divs off the page using absolute positioning and transitioning the left property using either hover state or javascript.
Hover the red div.
Codepen Example
Could you not set max-width to 100%, not set the actual width and float them side by side? With both overflow:hidden, as they expand it should create horizontal scrollbars.