There is a zoom property in css, it does what it needs, but there is no support in browsers (Firefox in particular). There is also a transform: scale () property, but the fact is that the main_div block becomes visible when using transform: scale (), which is not when using the zoom property. I need exactly this behavior.
Can the transform: scale() property be applied in such a way that it works like a zoom? Or what analogs does the zoom property have? How to be in this situation?
Here is my code. You need to check in Google Chrome, since Firefox's zoom property does not work
https://jsfiddle.net/tj2349f5/1/
html
<div id='main_div'>
<div id="second_div">Hello</div>
</div>
<input class="test_button" type="button" name="button_name" value="test">
JavaScript
let test_button = document.querySelector('input.test_button');
test_button.addEventListener('click', () => {
//second_div.style.transform = 'scale(0.5)';
second_div.style.zoom = 0.5;
});
The difference between a 'real' CSS zoom and a scale is that a scaled element does not change the space it takes up whereas a zoomed one does.
I am not absolutely sure whether this code does what you want as on my device I don't see the red appearing as described in the question [I think this is because my device is narrower]. What it does is change the width and height of the zoomed element alongside the scaling.
The effect on Chrome that I see is that the scrollbars change the same amount whether using this code or the real CSS zoom whereas using scale only the scrollbars don't change at all.
let test_button = document.querySelector('.test_button');
test_button.addEventListener('click', () => {
second_div.style.height = second_div.offsetHeight * 0.5 + 'px';
second_div.style.width = second_div.offsetWidth * 0.5 + 'px';
second_div.style.transform = 'scale(0.5)';
test_button.style.display = 'none';
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
div {
display: flex;
}
div#main_div {
display: block;
margin: 10px auto;
height: 80vh;
width: 80vw;
background: red;
overflow: scroll;
}
div#second_div {
height: 3000px;
width: 3000px;
background: green;
transform-origin: 0% 0%;
}
<div id='main_div'>
<div id="second_div">Hello</div>
</div>
<button class="test_button">CLICK TO MAKE IT LOOK LIKE A REAL CSS ZOOM BUT USING SCALE AND DIMENSION SETTING</button>
Note: if you scale back up remember to restore the dimensions as well.
Related
After 4 hours of trial and errors, I cannot find a way to get the width of the circle that is defined by a percent and convert it to pixels and make the circles height the same size as the width in pixels. Below is what I have right now. (I have tried many variations of this but cannot figure it out) Right now it only works on my screen. I try it on other devices and the height is just not right. This button is created onload.
Example: Circle Width = 12% , the Pixel Value of 12% on a screen is "70px". So somehow make Circle Height = 70px.
<!DOCTYPE html>
<head>
<title>Circle Test</title>
<meta charset='UTF-8'>
<script type="text/javascript" src="/js/fs"></script>
</head>
<body>
</body>
</html>
// Creates a button
var mainButton = document.createElement("button");
mainButton.style.width = "10%";
// Get the Screens Avaliable Width and Get 10% of it and convert it to pixels
var wad = screen.availWidth * .1 + "px";
// Thinking this would return the pixel amount the circle button is, but it only works on the regular screen and not when resized. It also does not work for mobile.
console.log(wad);
mainButton.style.height = wad;
You set the width of your button to 10% of its containing block's width, and the height to 10% of the width of one of
The available area of the rendering surface of the output device, in CSS pixels.
The area of the output device, in CSS pixels.
The area of the viewport, in CSS pixels.
It's very likely that these are measurements of two different things, or that resizing the window will affect one but not the other. Fortunately, CSS has a unit for "percentage of the window's width": vw. Set your button's height and width in vw units, and you don't need any JavaScript:
button {
width: 10vw;
height: 10vw;
border-radius: 50%;
}
<button>Go</button>
If you really meant that the button is 10% as wide as its container, even if its container isn't as wide as the whole window, you can use the padding-bottom technique detailed in this answer. Unlike height, percentages in padding refer to the width of the containing block:
.wrapper {
width: 40%; /* here I use 40% instead of 10% for aesthetics */
padding-bottom: 40%; /* should match width */
position: relative;
}
.wrapper > button {
display: block;
position: absolute;
width: 100%;
top: 0;
bottom: 0;
border-radius: 50%;
}
/* the rest is just to make figuring out
the exact width of the button difficult */
body {
display: flex;
align-items: stretch;
height: 90vh;
}
body > div {
flex: 1 1 0;
background: rebeccapurple;
margin: 0 4px;
}
<div>
<div class="wrapper"><button>Go</button></div>
</div>
<div></div>
<div></div>
And finally, just for completeness, if you really must get the computed width from JavaScript, you can use window.getComputedStyle:
let button = document.querySelector('button');
let width = window
.getComputedStyle(button)
.getPropertyValue('width');
console.log(button.style.height = /* DO NOT DO THIS */ width);
button {
width: 40%;
border-radius: 50%;
}
/* the rest is just to make figuring out
the exact width of the button difficult */
body {
display: flex;
align-items: stretch;
height: 90vh;
}
body > div {
flex: 1 1 0;
background: rebeccapurple;
margin: 0 4px;
}
<div>
<button>Go</button>
</div>
<div></div>
<div></div>
If you try putting that into a resize handler, though, performance will suffer.
I created this demo:
http://cristiantraina.altervista.org/boxfall/
When you click, it creates a red falling box.
The problem is that using only css there are no ways to detect the size of the screen, in fact in my demo I specify that the box has to fall for 1000px, regardless of the actual height of the screen.
This is the code of the keyframe:
#include keyframes("fall"){
to{
top: 1000px;
}
}
I can't use bottom:0px; because I wouldn't know from where to start the fall, and I didn't solve my main problem.
This is the FallBox.js script:
function FallBox(x, side, parent){
this.x = x;
this.parent = parent || $("body");
this.side = side || Math.random()*200;
this.createBox();
this.fall();
}
FallBox.prototype.createBox = function(){
box = document.createElement('div');
$box = $(box); // I hate brackets
$box.addClass("box");
$box.css({
width: this.side+"px",
height: this.side+"px",
left: this.x+"px",
top: "-"+(this.side+5)+"px"
});
this.box = $box;
}
FallBox.prototype.fall = function(){
this.parent.append(this.box);
this.box.addClass("fall");
}
I know that I could use overflow:hidden; in the parent div, but I don't think that this is the ideal solution. First because a user can have got a screen with a superior height, then because I want to the box stops when it meets the edge, as the border was ground and it shouldn't pass through.
Another solution that I found on the web, it's to use the CSSOM API, but not even mozilla developers are sure of the compatibilty of these.
So, how can I stop an animation when it meets the screen edge, since javascript fails to inject properties?
Thank you.
If you're looking for a css-only solution, you could use the css calc feature (http://caniuse.com/#feat=calc) in combination with vh (http://caniuse.com/#search=vh).
document.querySelector(".box").addEventListener("click", function() {
this.classList.toggle("is-dropped");
})
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.box {
position: absolute;
top: 0;
left: 200px;
width: 100px;
height: 100px;
background: red;
transition: top 2s;
}
.box.is-dropped {
top: calc(100vh - 100px);
}
<div class="box"></div>
You coul use the translatey() CSS transform function to shift each div up by 100% of its own height. That way you would just need 2 rules to change the value of the top position without having to worry about height in each case.
(function(d,M){
var div=d.createElement("div"),
wait=0,size;
d.body.addEventListener("click",function(){
if(!wait){
wait=1;
div=div.cloneNode(1);
div.classList.remove("go");// necessary so that newly created divs don't just get added to the bottom of the page
size=M.max(M.floor(M.random()*200),50);
div.style.height=div.style.width=size+"px";
div.style.left=M.max(M.floor(M.random()*this.offsetWidth)-size,0)+"px";
this.appendChild(div);
setTimeout(function(){
div.classList.add("go");// adding this class starts the animation.
wait=0;
},5);
}
},0);
})(document,Math);
*{box-sizing:border-box;margin:0;padding:0;}
html,body{height:100%}
div{
background:#000;
border:1px solid #fff;
transition:top 2s linear;
position:absolute;
top:0;
transform:translatey(-100%);
}
div.go{
top:100%;
}
ORIGINAL SOLUTION
As the height of the box is being set dynamically in your JavaScript, your CSS isn't going to know the height of each box but that doesn't stop you using the CSS calc() function to set the top position you want to animate each to, much like you currently do to set its starting top position. Here's a quick, rough example, with an alternative solution in the comments that doesn't use calc(), if you'd prefer.
var div=document.createElement("div"),
wait=0,size;
document.body.addEventListener("click",function(){
if(!wait){
wait=1;
div=div.cloneNode(0);
size=Math.max(Math.floor(Math.random()*200),50);
div.style.height=div.style.width=size+"px";
div.style.left=Math.max(Math.floor(Math.random()*this.offsetWidth)-size,0)+"px";
div.style.top="-"+size+"px";
this.appendChild(div);
setTimeout(function(){
div.style.top="calc(100% - "+size+"px)"; /* This is the important bit */
// div.style.top=document.body.offsetHeight-size+"px"; /* Alternative solution, without using calc() */
wait=0;
},5);
}
},0);
*{box-sizing:border-box;margin:0;padding:0;}
html,body{height:100%}
div{
background:#000;
border:1px solid #fff;
transition:top 2s linear; /* Using a transition instead of an animation */
position:absolute;
}
Having a small problem. (Refer to fiddle)
I've got a container in my project that has been rotated 180 deg, with a container inside that has been rotated another 180 back to the original state.
I need to invert the scroll.
How would i go about this?
Dont mind wasting your time with a method, that reverts the basic setup.
The basic setup has to stay.
http://jsfiddle.net/vavxy36s/
Description of fiddle:
"Start" marks the initial string and "end" ofcourse the last one.
If you try scrolling you will realize, that it's inverted as to how one would normally scroll.
.class1 {
height: 200px;
background-color: blue;
color: white;
width: 100px;
overflow-y: scroll;
overflow-x: hidden;
direction: rtl;
-webkit-transform: rotate(180deg);
}
.class2 {
direction: ltr;
-webkit-transform: rotate(180deg);
}
EDIT: Just mousewheel scroll, has to be inverted.
Edit: Your original setup has different behaviors in Chrome and in [IE & Firefox]. In Chrome, the scroll is already inverted, but in FF and IE, the scroll remains normal. My solution reverts it in both cases, but the behaviors remain different across browsers.
You could add these styles:
/* ...
Your original styles
...
*/
.class1 {
overflow: hidden;
position: relative;
}
.class2 {
position: absolute;
bottom: 0;
}
And then, using jQuery, modify the bottom CSS property of .class2:
var scrollPos = 0,
diff = $('.class2').height() - $('.class1').height();
$('.class1').on('mousewheel', function(e) {
scrollPos = Math.min(
0,
Math.max(
-diff,
scrollPos + e.originalEvent.wheelDelta
)
);
$('.class2').css('bottom', scrollPos);
});
JS Fiddle Demo
You could use the mousewheel library to catch and invert the scroll movement.
$(".class1").mousewheel(function(event) {
event.preventDefault();
this.scrollTop -= (event.deltaY * event.deltaFactor * -1);
});
You can view a demo here: http://jsfiddle.net/fduu20df/1/
I'm trying to develop a jQuery plugin that utilizes CSS values and modifies them. The problem, however, is that Firefox and Opera seem to not like keeping track of the units of the property's value. In Retrieving percentage CSS values (in firefox), the asker wants to get the percentage of a CSS property. I want to get the CSS property as a percentage with javascript if it's specified as a percentage in its CSS or as pixels if it's specified as pixels. I don't want to rely on any libraries other than jQuery, although it doesn't seem to be able to do what I'm wanting either.
CSS
#element{
margin-left: 10%;
}
Javascript
$('#element').css('margin-left'); // returns 29px in Firefox, but 10% in Chrome
getComputedStyle(document.getElementById('element')).getPropertyValue('margin-left'); // returns 29px in Firefox, but 10% in Chrome
This example is using css width, but the principle can be applied to any attribute that may be specified in %
CSS
.oneThirds {
width: 25%;
background-color: red;
}
.half {
width: 50%;
background-color: green;
}
.twoThirds {
width: 75%;
background-color: yellow;
}
HTML
<div class="oneThirds">One third</div>
<div class="half">Half</div>
<div class="twoThirds">two thirds</div>
Javascript
var elements = document.getElementsByTagName("div");
Array.prototype.forEach.call(elements, function (element) {
var parentStyle = window.getComputedStyle(element.parentNode);
var elementStyle = window.getComputedStyle(element);
var widthPercent = (parseFloat(elementStyle.width) / parseFloat(parentStyle.width)) * 100;
console.log(widthPercent);
});
Output
25
50
75
On jsfiddle
On some browsers you may need to do a little rounding of the floating point.
I have centered (position: absolute; left: 50%; margin: -50px;) 100px width div (container).
It has absolutely positioned child div with overflow: hidden, its size is 100x2000 px (such height is for test purposes, as described below).
There is an image in child div, it is absolutely positioned.
The image is 3100x100 px, it contains frames of animation.
I am animating this image by changing its style.left from 0 to -1100px, step is 100px.
Everything is fine, but I encounter weird issue when body width is not even.
It can happen if there is scrollbar and the scrollbar has odd width (it happens for me on Chrome/Win32 for example).
In this case image visually shifts by 1 pixel horizontally as soon as animated image goes through screen edge (for 1920x1080 it happens roughly at 9-10 frame of animation).
I can't find workaround for this behavior.
Working example reproducing the problem can be found here
Child div height is set to 2000px to make sure scrollbar is visible.
If your scrollbar has even width, you can reproduce the problem by resizing your browser window to odd width.
That happens because of the browsers rounding engines. Webkit apparently has some problems with 50% on even and odd widths.
One way to overcome the issue - re-position the .outer element based on window width
document.getElementById( 'outer' ).style.left = Math.floor( window.innerWidth / 2 ) + 'px';
DEMO
You need to change .inner img position to relative and update your javascript. I made changes for you, so here is your solved code:
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<style>
body {
background-color: #000000;
}
.outer {
position: absolute;
left: 50%;
margin-left: -50px;
}
.inner {
position: absolute;
width: 100px;
height: 2000px;
overflow: hidden;
}
.inner img {
position: relative;
top: 0;
left: 0;
}
</style>
</head>
<body>
<div class="outer">
<div class="inner">
<img src="http://lorgame.ru/test.png" id="img">
</div>
</div>
<script language="JavaScript">
var framesCount = 30;
var framesCurrent = 0;
var framesMoveLeft = true;
var img = document.getElementById('img');
var interval = setInterval(function() {
if(framesMoveLeft == true){
framesCurrent++;
img.style.left = (img.offsetLeft - 100) + 'px';
if(framesCurrent == framesCount) framesMoveLeft = false;
} else { // Move right
framesCurrent--;
img.style.left = (img.offsetLeft + 100) + 'px';
if(framesCurrent == 0) framesMoveLeft = true;
}
}, 100);
</script>
</body>
</html>
To me this seems like a bug in Chrome. When percentages are defined in integers, they behave rather unexpectedly. Try to define the position as a decimal instead:
.outer {
position: absolute;
left: 49.99999%;
margin-left: -50px;
}
I tested this on the fiddle and it seems to do the trick.