Using transform and element positioning/size - javascript

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

Related

Html-Css image stretched

I'm building a memory cards game with HTMl, CSS and JS to practice.
This is what I've done so far: https://spomin.krix12.repl.co/
As you can see, the image of the question mark and the image of the flipped card is streched a little bit.
This is the CSS code for it:
.memory-game {
width: 640px;
height: 640px;
margin: auto;
display: flex;
flex-wrap: wrap;
perspective: 1000px;
}
.memory-card {
width: calc(25% - 10px);
height: calc(33.333% - 10px);
margin: 1px;
position: relative;
transform: scale(1);
transform-style: preserve-3d;
transition: transform .5s;
box-shadow: 1px 1px 1px rgba(0,0,0,.3);
}
memory-card is inside memory-game. How can I fix the streched images? Is there a problem in html(I can provide you the code if needed) or css or should I crop the images itself to some ratio?
I would appreciate your help.
1. First solution:
The first column is using div tag in change of img, which could be a non-feasible solution accesibility-wise. This is how I've done it:
<div class="back-face" style="
height: 100%;
background-image: url('slike/emoji-ji/zaprto.png');
background-size: contain;
background-repeat: no-repeat;
background-position: center;
"></div>
2. Second solution:
Using flex! (as Hades mentioned below)
Put the img inside a div, then make that div a display: flex;, and turn its content to align-items: center;. The image, in turn, needs a few properties to know how to render width and height, which you can adjust to your needs.
<div class="back-face" style="display: flex;align-items: center;">
<img src="slike/emoji-ji/zaprto.png" alt="zaprto" style="
width: 100%;
height: 50%; // or auto
">
</div>
3. Third and best solution:
Let's use what we learned so far, and change a lot of code around! If you want all of them to look like the third one, here's the steps:
Change the CSS:
.memory-card {
width: calc(25% - 10px);
height: auto;
margin: 1px;
position: relative;
transform: scale(1);
transform-style: preserve-3d;
transition: transform .5s;
box-shadow: 1px 1px 1px rgb(0 0 0 / 30%);
/* add the following lines which used to be in img */
border-radius: 5px;
background: #1C7CCC;
display: flex;
align-items: center;
}
.front-face, .back-face {
/* a few things removed */
width: 100%;
position: absolute;
backface-visibility: hidden;
}
.front-face {
transform: rotateY(180deg);
/* add the following line to keep consistency */
padding: 20px;
}
And resulting html will look like:
<div class="memory-card" data-framework="gospod" style="order: 4;">
<img class="front-face" src="slike/emoji-ji/gospod.png" alt="vesel">
<img class="back-face" src="slike/emoji-ji/zaprto.png" alt="zaprto">
</div>
Barely any minor changes!
Final Thoughts
Remember, using inline style within your html is an antipattern! Make sure to refactor the code provided into your own css classes.
You can keep the images from stretching by only specifying a specific width or height (but not both).
You might want to wrap the images in a div that sizes to the size of the parrent and centers the image within it (For instance by using a flexbox with justify-content: center; and align-items: center;)

How do i make my image move across the page even when the resolution of screen changes

I have an image which goes from one side off the screen to other. However, when I open the HTML on a different sized computer/laptop, it does not fit and looks out of place. How do I fix this?
CODE:
body {
text-align: center;
}
div.container {
text-align: left;
width: 710px;
margin: 0 auto;
border: 12px solid black;
border-radius: 10px;
}
div.content {
width: 700px;
min-height: 400px;
background-color: white;
padding: 5px;
}
#-webkit-keyframes mini {
from {
left: 410px;
}
}
.mini {
position: absolute;
top: 280px;
left: 950px;
width: 166px;
height: 70px;
z-index: 10000;
-webkit-animation: mini 3s;
animation: mini 8s;
}
<div class="container">
<div class="content">
<img src="Media/buscartoon.jpg" class="mini" />
</div>
</div>
maybe set initial left and top values
.imganim {
width:100px;
height:60px;
position:absolute;
-webkit-animation:myfirst 5s;
animation:myfirst 5s;
left: 0;
top: 0;
}
Your .content and .container have no position set, so I guess it's defaulting to the next parent element that does have these set.
Pop this on your .content div:
position: relative;
the image is still going to go over the limits because of left: 100% but adding a relative position to the container may well help you get to the next problem.
If you want the image to sit flush with the edge of the container rather than running over, you can also change your left: 100% to:
left: calc(100% - 100px)
...where 100px is the width of the element.
edit: jsfiddle example https://jsfiddle.net/w56r2xnr/
Try the following css classes that i have ammended. I have kept the top at 5px which makes room for the 5px padding within the content div. Also the 50% transformation formal includes the left 100% - (width of the image + right-padding).
You can now adjust the top to make it as you see fit.
CSS changes:
div.content {
width: 700px; min-height: 400px;
background-color: white; padding: 5px;
position: relative;
}
/* Chrome, Safari, Opera */
#-webkit-keyframes myfirst
{
0% {left:0%; top:5px;}
50% {left: calc(100% - 105px);}
100% {left:0%; top:5px;}
}
/* Standard syntax */
#keyframes myfirst
{
0% { left:0%; top:5px;}
50% {left: calc(100% - 105px);}
100% {left:0%; top:5px;}
}
Sample: http://codepen.io/Nasir_T/pen/ZBpjpw
Hope this helps.
[Edit - Code changed in question]
I think in both scenarios you will need to set the content div with position:relative to keep the image contained within it as the image itself is position:absolute. Along with that you need to use percentage values for the left and top in order for the animation and the position to be in the right place regardless of the size of the screen.
For the updated code in question please check the following code sample:
http://codepen.io/Nasir_T/pen/ObRwmO
Just adjust the key frame left percentage according to your need.

Resize child div element to fit in parent div on window resize

I have a div element (shown with red border in the image below), which I want to be able to fit in its parent div when the window is resized and not fall into the next line (the parent is the one with the green border).
I want the red div to have a starting width: 949px (in my current screen) in order to fit the entire space available as shown in the image, but be resizable, so that it doesn't fall into the next line if width: 949px is to much to fit.
In essence, I want it at all costs to cover the area it covers in the image even if in a narrower screen that means it will be like 10px wide.
How can I achieve this? Any solution using CSS, JavaScript or jQuery will be gladly accepted.
The image:
CSS:
#parent {
text-align: center;
width: 90%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: inline-block;
}
#child1-row2 {
text-align: left;
vertical-align: middle;
width: 288px;
display: inline-block;
}
#child2-row2 {
text-align: left;
vertical-align: middle;
width: 288px;
position: relative;
margin: 0 25px 0 25px;
display: inline-block;
}
#child3-row2 {/* The one with the red border */
vertical-align: middle;
height: 452px;
width: 949px;
overflow: hidden;
position: relative;
display: inline-block;
}
You can use flexbox to do this by using the flex-grow property.
HTML :
<div id="main">
<div id="box1">1</div>
<div id="box2">2</div>
<div id="box3">3</div>
</div>
CSS :
#main {
display: flex;
flex-flow: row;
width:100%;
min-height:50px;
}
#box1{
background-color:red;
width:100px;
}
#box2{
background-color:blue;
width:100px;
}
#box3{
background-color:green;
flex-grow: 1;
}
Here is a working JSFiddle
You can use css calc function for this. Support for calc seems to be quite good now.
As you have mentioned, the left side divs are of fixed width, say 120px each. Also suppose the margin between them is 30px. So, the total width left for your red div is 100% - (2*120 + 2*30)px i.e. (100% - 300px ).
#red-div
{
width: calc(100% - 300px);
}
Add % width or you can do following :
$(window).resize(function() {
var window_width = $(window).width();
var w1_width = $('.div1').width(); // The first element width
var w2_width = $('.div2').width(); // The second element width
var main_div_width = window_width - (w1_width+w2_width+gutter[i.e margin between all 3 elements]);
$('.main_div_width').css('width', main_div_width);
});

make div bigger and animate bigger section upwards on hover

I am trying to animate a div upwards when a user hovers on the div.
I am able to animate the div making it bigger, however the animation happens downwards. I am trying to keep the bottom of the div remain in the same place, and have a smooth animating increasing the size of the div upwards.
See jsfiddle here which demonstrates what my code is currently doing.
Please see code below:
.box {
height: 170px;
padding-bottom: 15px;
width: 50%;
}
.content {
background-color: #e3e4e6;
height: 100%;
text-align: center;
}
.content:hover {
height: 110%;
}
<div class="box">
<div class="content">TEST</div>
</div>
You can do this using transform:scaleY() and set the transform-origin to bottom. I also put a margin-top:100px to see the effect better. Also you can use transition to make the scale smoother
You also need to scale back the text.
See here: jsfiddle
You need to scale the text back to it's original state in the same time that you scale the div. so if you scale the div 2 times. You need to scale back the text with 1/2 , same if you scale 3 times...scale back with 1/3
In this case you enlarge .content by 1.5 so you need to scale down the text inside by 1/1.5 = 0.66
Code:
.box {
height: 170px;
padding-bottom: 15px;
width: 50%;
}
.content {
background-color: #e3e4e6;
height: 100%;
text-align: center;
margin-top: 300px;
transition:0.3s;
}
.content:hover p {
transform: scaleY(0.66)
}
.content:hover {
transform: scaleY(1.5);
transform-origin: bottom;
}
<div class="box">
<div class="content">
<p>
TEST
</p>
</div>
</div>
Try it like this (I have no other idea...): You can give to the class "box" a bigger height (I put a red border around, so you can see it) than the class "content". After that, you can use flexbox, to put the class "content" on the bottom. After that, you can do it with hover to change your heigth upwards and fill it. With transition you can make a nice animation. I hope this is good enough. Perhaps there is also a way with jQUery at the moment I havn't got an idea. Let me know, if this helps you (I'm not sure if I understanded the question well) - Cheers. (Important: This heights and so on are just random values for testing)
.box {
display: flex;
justify-content: flex-end;
flex-direction: column;
height: 100px;
border: 1px solid red;
}
.content {
background-color: #e3e4e6;
height: 50px;
width: 100%;
text-align: center;
-webkit-transition: height 1s;
/* Safari */
transition: height 1s;
}
.content:hover {
height: 100%;
}
<div class="box">
<div class="content">TEST</div>
</div>
If you just want to use css, just use:
.content:hover {
margin-top: -50px;
height: 110%;
}
See jsFiddle
since there isn't any space at top to expand, you may give an extra margin initially and remove it on hover like this JsFiddle -
.box {
height: 170px;
padding-bottom: 15px;
width: 50%;
}
.content {
background-color: #e3e4e6;
height: 100%;
text-align: center;
margin-top:25px;
}
.content:hover {
height: 110%;
margin-top:0;
}
Set top property with the value of height - 100 * -1
https://jsfiddle.net/x3cL1cpt/7/
.content:hover {
height: 110%;
top: -10%;
position: relative;
}
Why position relative? It's because I move the box, but without modifying the space that the box occuped. If you need to modify that space, change top with margin-top.
Replace this CSS with your current, needed to add transition:
.box {
height: 170px;
padding-bottom: 15px;
width: 50%;
}
.content {
background-color: #e3e4e6;
height: 100%;
text-align: center;
transition: 1s all ease;
}
.content:hover {
transform: scaleY(1.2);
transform-origin: bottom right;
}

How to make the parent div adjust in size to contain the CSS-Rotated child div?

The Title says it all: "How to make the parent div adjust in size to contain the CSS-Rotated child div?"
This is what I get currently:
HTML:
<div id="container">
<div id="rotator">
<h1>TEXT</h1>
</div>
</div>
CSS:
#container {
display: inline-block;
border: 1px solid gray;
padding: 10px;
overflow: hidden;
}
#rotator {
display: inline-block;
width: 200px;
height: 500px;
background-color: rgb(130, 310, 130);
border: 1px solid blue;
text-align: center;
line-height: 500px;
-moz-transform:rotate(90deg);
-webkit-transform: rotate(90deg);
-o-transform:rotate(90deg);
-ms-transform:rotate(90deg);
transform:rotate(90deg);
}
Live Example
So, is there anyway to make the parent resize with child?
A CSS only solution would be best. If that's impossible, what's the best javascript way to do that?
Should support IE9
Based on #misterManSam's suggestion I update the live example to show the solution.
found here
Change the width of the div.container when rotated. Add negative margin and left margin to #rotator.deg90in CSS.
Look at this example :)
Javascript
function to90() {
var elm = document.getElementById("rotator");
console.log(elm);
elm.className = "deg90";
//add these lines
document.getElementById('container').style.width = "500px";
document.getElementById('container').style.height = "200px";
}
CSS
#rotator.deg90 {
/*add this*/
margin-top: -150px;
margin-left: 200px;
-moz-transform:rotate(90deg);
-webkit-transform: rotate(90deg);
-o-transform:rotate(90deg);
-ms-transform:rotate(90deg);
transform:rotate(90deg);
}
Here you go: http://jsbin.com/viyacaji/11/edit
Just rotate the container in the jS functions, don't move the rotator div. Because basically, what you're trying to achieve is the same as when you rotate the parent div.
Any query?

Categories

Resources