I am trying to implement a CSS3 animation on my site where 2 divs would squeeze together another div with a background image. It's pretty hard to explain, so I made a quick video. Please note that the problem I want to solve is present on this video.
What I'd like to do is when animating the height of a div, it wouldn't shrink to it's horisontal center instead of it's top.
Can this be done in any way?
My HTML:
<div id="container">
<div id="top-bar">
<ul id="nav">
<li>Főoldal
</li>
<li>Szolgáltatások
</li>
<li>Portfólió
</li>
<li>Kapcsolat
</li>
</ul>
</div>
<div id="content">
<div id="card">
<!-- The orange card : irrelevant -->
</div>
<div id="main">
<div id="inner-content"></div>
</div>
</div>
<div id="bottom-bar">
<div id="logo">
<!-- Logo Image -->
</div>
</div>
</div>
Please check the jsFiddle examples for the full code.
jsFiddle code
jsFiddle Full Screen Result
I have created a fiddle here. Every time you click the button it will add/remove the class that has the scaling transform.
CSS:
.box {
width: 300px;
height: 300px;
background: black;
-webkit-transition: all .6s ease-in-out;
transition: all .6s ease-in-out;;
}
.box-change {
-webkit-transform: scale(0,0);
}
JS:
$(function() {
$("#bt").click(function() {
$(".box").toggleClass("box-change");
});
});
HTML:
<div class="box"></div>
<input type="button" value="Let's Do This Thing" id="bt">
You can change CSS to this:
.box-change {
-webkit-transform: scale(1,0);
}
for shrinking to "horizontal center" effect.
See this demo
fiddle
The CSS is:
div {
width: 200px;
position: absolute;
}
.mid {
background: url("http://placekitten.com/200/300");
height: 200px;
top: 100px;
-webkit-transition: all 2s;
transition: all 2s;
}
.top {
top: -100px;
height: 100px;
background-color: gray;
}
.bottom {
bottom: -100px;
height: 100px;
background-color: gray;
}
.mid:hover {
height: 0px;
margin-top: 100px;
background-position: 0px -50px;
}
The trick is to modify the height, and at the same time change the margin-top so that the center stays at the same place. And at the same time change the background position, also accordingly.
I have done this effect because this is what I saw in the video, even though your question seems to ask for the background shrinking. If what you want is the later, please say so.
Related
I am trying to place the content of my homepage below my navabr which is located at the center of the page.
I was able to place the content below the navbar, but it changes when I change the window's height.
How do I make it stick below the navbar?
this is the css:
.content {
position: relative;
height: 100vh;
transition: 0.3s;
}
.homeNav {
transition: 0.3s;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 100%;
}
.homeContent {
position: absolute;
transition: 0.3s;
top: 65%;
}
This is my html:
<body>
<div class="container content">
<nav class="homeNav" id="all">
<img src="/images/400x200.png" class="img-fluid mx-auto d-block" />
<div class="row bg-info">
NAVIGATION BAR HERE
</div>
</nav>
<div id="main-page" class="homeContent">
</div>
</div>
</body>
Please note that this is a single-page application, and the content of the main-page is obtained from a separate HTML file.
You can add css to the body element
body{
margin-top: 200px;
}
That's it.
Alternatively, you can wrap the header and bottom content in a div and then give margin-top to that div element.
<div class="wrapper">
<nav>Header Area</nav>
<!-- Everything else goes here -->
</div>
CSS for wrapper class:
.wrapper{
margin-top: 200px;
}
I am rotating an image using a CSS transform like this...
https://jsfiddle.net/7ed1aqrt/
.content1{background:teal;}
.imagecontainer{text-align:center;background:wheat;width:100%;}
img{transform: rotate(90deg);}
.content2{background:pink;}
<div class ="content1">Content 1</div>
<div class ="imagecontainer">
<img src="https://dummyimage.com/300x200/000/fff">
</div>
<div class ="content2">Content 2</div>
But the rotated image is breaking out of it's container and overlapping the divs above and below it.
Is there a way to stop this from happening?
Just try adding overflow: hidden; to your image container. When rotating an image that has different widths/height then you will need to offset it with a margin. See the updated answer below:
Updated answer
.content1 {
background: teal;
}
.imagecontainer {
text-align: center;
background: wheat;
width: 100%;
overflow: hidden; /* Prevent overflowing of nested elements */
}
img {
display: block;
transform: rotate(90deg);
margin: 50px auto; /* account for 100px width/height difference */
}
.content2 {
background: pink;
}
<div class="content1">Content 1</div>
<div class="imagecontainer">
<img src="https://dummyimage.com/300x200/000/fff">
</div>
<div class="content2">Content 2</div>
I had the same issue, I just added padding to the image and it stopped overlapping. Try adding this code to the .image-container class
.image-container{
padding : 20px;
}
I don't think it's the perfect solution, but it helps.
I got a strange problem with IE11 and 10 when i try to animate a transform translateY() with transitions. I have a skybox with a sky inside which is 500vh height. this sky has to be moved up and down according to the current section in the viewport.
the viewport is an absolute:position element which handels the content and so on.
when i now set the sky to lets say transform: translateY(-400vh), then it works correctly in every browser except IE11 and 10. it looks like the element disappears when the transition starts and appears when the transition is finished.
You can find a short example in this fiddle here: https://jsfiddle.net/90q394vz/4/
body, html {
height:100%;
width:100%;
overflow:hidden;
}
* { box-sizing:border-box; }
header {
position:fixed;
top:0;
left:0;
width:100%;
background:#fff;
z-index:100;
}
.skybox {
//height: 100%;
z-index: 1;
//width: 100%;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
overflow: hidden;
}
.skybox .sky {
height: 500vh;
width: 100%;
background: red;
transform: translateY(-400vh);
transition: all 0.8s ease-in-out;
}
.sec1 .skybox .sky {
transform: translateY(-400vh);
}
.sec2 .skybox .sky {
transform: translateY(-300vh);
}
.sec3 .skybox .sky {
transform: translateY(-200vh);
}
.sec4 .skybox .sky {
transform: translateY(-100vh);
}
.viewport {
width:100%;
height: 100%;
position: relative;
z-index:10;
text-align:center;
padding: 50px;
}
.viewport-content {
background: rgba(255,255,255,0.2);
margin: 100px auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header>
<span onclick="$('body').removeClass().addClass('sec1')">scroll 1</span>
<span onclick="$('body').removeClass().addClass('sec2')">scroll 2</span>
<span onclick="$('body').removeClass().addClass('sec3')">scroll 3</span>
<span onclick="$('body').removeClass().addClass('sec4')">scroll 4</span>
</header>
<div class="skybox">
<div class="sky">
<div style="height:100vh; padding:100px;">sky part 5</div>
<div style="height:100vh; padding:100px;">sky part 4</div>
<div style="height:100vh; padding:100px;">sky part 3</div>
<div style="height:100vh; padding:100px;">sky part 2</div>
<div style="height:100vh; padding:100px;">sky part 1</div>
</div>
</div>
<div class="viewport">
<div class="viewport-content">
im content in top of the sky yeahhh...ö
</div>
</div>
Any idea how to fix this?
UPDATE 1: After another test i think that IE is not able to use Transform with vh and vw units! Here is a small example of a simple translateX of 10vh. It goes in the opposite direction LOL. i have absolutely no idea whats going on there -.-
https://jsfiddle.net/8hne5ckd/3/
UPDATE 2 A few hours later i found out, that it seems to work with vh and vw units when i change the transforms from simple 2d transforms (translateY(-100vh)) to a translate3d(0, -100vh, 0). I have no idea why IE can handle vh and vw units withing the 3dtransforms but not in 2dtransforms.
Would be nice if someone with more knowledge could explain me why.
https://jsfiddle.net/8hne5ckd/7/
UPDATE 3 Ok it still does not work. either with transitions or animations. as soon as i use vw units, it looks just crap.
Thanks
I had a similar problem in IE, setting the initial value in 0.1vh instead of 0 helped me.
Try using % instead of vh with a translate3D transform (not translateY). That solved it in my scenario. Hope that works for you!
Let's assume I have a collapsible fixed-width sidebar defined like this:
HTML
<div class="container">
<div class="sidebar" id="sidebar">
SIDEBAR
</div>
<div class="content">
lorem bla bla
<button onclick="document.getElementsByClassName('sidebar')[0].classList.toggle('collapsed')">
toggle Sidebar
</button>
</div>
</div>
CSS
body {
margin:0;
}
.container {
display: flex;
min-height:100px;
}
.sidebar {
position: relative;
left: 0;
width: 200px;
background-color: #ccc;
transition: all .25s;
}
.sidebar.collapsed {
left:-200px;
margin-right:-200px;
}
Codepen here: http://codepen.io/anon/pen/pJRYJb
So here's the question:
How can I go from there to a flexible-width sidebar?
Here are the constraints:
no javascript (I want the browser to deal with the layouting – not me)
the sidebar must not overlap the content
when collapsed, the sidebar's right border needs to be aligned with the window's left border (to be able to attach an absolutely positioned tab on the right side that's always visible)
the width of the sidebar shouldn't change if collapsed to avoid reflows during the transition
smooth transition without any sudden jumps
modern CSS (flexboxes, calc) is fine
The main issue here is that I can't find a way to say margin-right: -100% where 100% refers to the width of sidebar
Any help will be greatly appreciated!
How about changing the width instead of position on click? I use max-width in this case, it works almost the same as unknown width. This will probably cause the content reflow on the sidebar, so use white-space:nowrap if it's acceptable.
http://jsfiddle.net/dn4ge901/
body {
margin: 0;
}
.container {
display: flex;
}
.sidebar {
background: #ccc;
transition: all .1s;
max-width: 1000px;
}
.sidebar.collapsed {
max-width: 0;
overflow: hidden;
}
<div class="container">
<div class="sidebar" id="sidebar">SIDEBAR</div>
<div class="content">lorem bla bla
<button onclick="document.getElementsByClassName('sidebar')[0].classList.toggle('collapsed')">toggle Sidebar</button>
</div>
</div>
Another workaround is using transform width position together, but the animation effect will be slightly different.
http://jsfiddle.net/vkhyp960/
body {
margin: 0;
}
.container {
display: flex;
}
.sidebar {
background: #ccc;
transition: all .1s;
}
.sidebar.collapsed {
transform: translateX(-100%);
position: absolute;
}
<div class="container">
<div class="sidebar" id="sidebar">
<div>SIDEBAR</div>
</div>
<div class="content">lorem bla bla
<button onclick="document.getElementsByClassName('sidebar')[0].classList.toggle('collapsed')">toggle Sidebar</button>
</div>
</div>
Piggy-backing off Pangloss' suggestion re: the transform... you can just apply a negative margin to the content if you know the width of the sidebar. No need to have the sidebar switch to absolute positioning.
#mixin transitionAll() {
transition: all .3s ease-out;
}
html, body {
height: 100%;
}
.container {
display: flex;
width: 100%;
height: 100%;
}
.sidebar {
flex: 1 0 300px;
background: #333;
height: 100%;
#include transitionAll();
&.is-collapsed {
transform: translateX(-100%);
}
}
.content {
width: 100%;
height: 100%;
padding: 1rem;
background: #999;
#include transitionAll();
&.is-full-width {
margin-left: -300px;
}
}
--
<div class="container">
<aside class="sidebar">
</aside>
<section class="content">
<button class="btn btn-primary">Toggle</button>
</section>
</div>
--
$(function() {
$('.btn').on('click', function() {
$('.sidebar').toggleClass('is-collapsed');
$('.content').toggleClass('is-full-width');
});
});
See the Pen LxRYQB by Jason Florence (#JFlo) on CodePen.
For what it's worth, I do have a partly js solution. The animation itself is done entirely with CSS, it just resolves the width:auto problem. You just set the width of the sidebar domElement with js, when the element is loaded:
domElement.style.width = `${parseInt(domElement.offsetWidth)}px`;
This resolves the 'unknown' width problem. And you can use your .collapsed approach just as you like to do. The only adjustment is that you'll need to add !important to the .collapsed {width: 300px !important;} width value.
I've got one line (not wrapped) text inside full width div.
Is it possible to animate this element text alignment so text moves to given side/center - I know I could mensure width and use relative/absolute positioning, but I dont find it straight solution and it also may cause some responsive issues?
Here is demo without animations yet.
I needed something similar today. I wanted a button that started with text aligned to the right, but then animated the text to center on hover/focus.
Here is what I came up with. The problem I have with several of the answers I have found is that they animate "position", which is not very performant. I wanted to use only "transform". This is a lot of markup just for centering button text, but seems to work well.
body {margin: 0}
ul, li {
margin: 0;
padding: 0;
}
li {
width: 30%;
padding: 10px 0;
}
button {
width: 100%;
height: 50px;
margin: 0;
}
.center-line {
position: absolute;
width: 2px;
height: 100%;
background: lightgray;
left: 15%;
top: 0;
}
.outer {
text-align: right;
transition: 200ms transform;
}
.inner {
display: inline-block;
transition: 200ms transform;
}
button:hover .outer {
transform: translateX(-50%);
}
button:hover .inner {
transform: translateX(50%);
}
<ul>
<li>
<button>
<div class="outer">
<div class="inner">Text 1</div>
</div>
</button>
</li>
<li>
<button>
<div class="outer">
<div class="inner">Text Two</div>
</div>
</button>
</li>
<li>
<button>
<div class="outer">
<div class="inner">Text Longer Three</div>
</div>
</button>
</li>
</ul>
<span class="center-line" />
text-align property is not animatable, so you can't use it with css transition nor with jquery animate .. Your best shot would be the positioning (use percentage units to retain responsivity).
Hope this helps ...
Maybe javascript created marquee would help you out here? <marque> tag is not best way but maybe js marquee would suit you.
Marquee (with optional start/stop buttons)
Update: As I understand that marquee would not be best for your needs I came out with another solution using margin-left and changing its value.
Value for right button would depend on how long text you would have there but you can always check that width elements width and adjust in code. I have updated the fiddle with that change in mind: final Fiddle