if I have element,and I want to translate it for 50px more than the current value.Why I can't do something like this?
element.style.transform="translateX(+=50px)"
Is there a way to do something like that?
If your transform is set in a stylesheet, element.style.transform will return an empty string. You must use getComputedStyle.
To get the x translation as an integer use:
var transform = parseInt(window.getComputedStyle(element, null).transform.split(',')[4]);
Then use this to increment by 50 pixels:
element.style.transform = "translateX(" + (transform + 50) + "px)"
Here is a fiddle: https://jsfiddle.net/uhuh9r64/
JS does not understand CSS and vice versa, but CSS can solve this on its own.
Unknown to most people, the ECMAScript (proper name for JS) specification and the CSS and DOM standards are maintained by different groups and have little ability for interoperation. Most interfacing between them happens with JS invoking the APIs, but JS does not typically consider or care what API it invokes.
That is, JS has no explicit support for CSS and sees this as a string.
That doesn't matter when you can transform elements using pure CSS, without JS needing to be involved (although you can apply transforms from JS). A simple position transform, even in 2D, can easily move an element down by 50px.
The translateX() is a css function used to move the element horizontally on the plane. This transformation is define by a length that define how much it moves in horizontally. The sample code example is for you in the bellow.....
exm.html
<div>
<p>welcome</p>
<p class="transformed">bar</p>
<p>thanks</p>
</div>
exm.css
p {
width: 50px;
height: 50px;
background-color: teal;
}
.transformed {
transform: translateX(10px);
background-color: blue;
}
Related
I want to make a plane with HTML element in webGL and can do an action like real HTML, example: make a button and when we click it, it give us an animation feedback and run the function. I already seek the answear and found html2canvas and rasterizeHTML.js but it just give like an image not natural HTML. Is there any library or any way for me to do like example above. Thanks in advance...
NOTE : For some reason i can't use CSS3DRenderer in Three.js
For example image you can see in the link below:
If I understand correctly, you're wanting to define an interactive user interface with HTML that is rendered with "3D perspective".
There are a few ways this can be done - one would be to not use WebGL at all, and instead use CSS3 transforms and perspective:
/* Add click handler to demonstrate that elements are still
interactive, even when orientated in 3D space */
const button = document.getElementById("clickme");
button.addEventListener("click", () => {
alert("hi!");
});
/* Optional - just for purpose of demonstration */
#keyframes movement {
from {
transform: rotateY(20deg);
}
to {
transform: rotateY(-20deg);
}
}
/* Define a "perspective wrapper" to give
the child elements the effect of 3D perspective */
.perspective {
width: 500px;
perspective: 500px;
perspective-origin: 50% 50%;
padding: 1rem;
}
.surface {
/* Style the UI surface using regular CSS */
background: red;
padding: 1rem;
text-align: center;
/* Orientates the surface in 3D space */
transform: rotateY(20deg);
animation: movement 5s infinite;
}
<div class="perspective">
<div class="surface">
<button id="clickme">Click me, I'm in 3D and I'm interactive!</button>
</div>
</div>
This approach retains the benefits of declarative HTML, the existing JavaScript DOM WebAPI, while also giving you smooth, hardware accelerated rendering of that HTML in 3D perspective.
Alternatively, if you are needing to render interactive user interfaces within a canvas element (ie, without CSS3 transforms), you could consider a library like Babylon.js which offers a pretty comprehensive GUI framework.
Here is an example show casing a fairly complex GUI rendered in 3D space, built using the Babylon.js framework - the caveat is that the GUI is defined with JavaScript (rather than HTML) however is more akin to the "Three.js way" of doing things.
The values returned by getComputedStyle are resolved values. These are usually the same as CSS 2.1’s computed values, but for some older properties like width, height, or padding, they are instead the same as used values.
-- MDN: window.getComputedStyle() notes
So is it currently possible to get the resolved value of height as it was specified in stylesheet?
I.e. know that some element's computed ..px (= used) height was specified as height: 100%; in style sheet? (100% being the resolved value in question.)
Is there some new specification regarding this problem in consideration?
Edit 2020-08-17: see very similar question and excellent answer from 2012: Is there a cross-browser method of getting the used css values of all properties of all elements?
(Sadly, noting seem to ave changed since then.)
No, there is no specification or functionality that supports or enables this method. There are plenty of ways to go the other direction, including...
getBoundingClientRect()
offsetHeight
getComputedStyle
... but none that will retrieve the exact percentage specified in the CSS, unfortunately.
You can try, as I've done below.
RegEx
If your height is specified as an inline style, you could RegEx it out of the attribute like so1:
let elem = document.getElementsByTagName("div")[0];
let re = /(?<=\height:\s+?)[^\;]+/i;
console.log(re.exec(elem.getAttribute("style"))[0]);
<div style="color: black; height: 100%; background: white;"></div>
This is terrible practice, though, and could be janky if there are multiple width declarations (which should never happen, but we're already in "bad code land", so why not?). Of course, this ignores the fact that inline styles should generally be avoided in the first place, so this probably won't apply to you.
Bounding calculations
It's also possible to calculate the value yourself by comparing the height of the element with the height of its parent.
let elem = document.getElementById("inner");
let pare = elem.parentElement;
let hrat = `${100*(elem.offsetHeight / pare.offsetHeight)}%`;
console.log(hrat);
#container {
height: 300px;
width: 400px;
background: repeating-linear-gradient(45deg, rgba(255,0,0,0.35), rgba(255,0,0,0.35) 10px, rgba(255,0,0,0.1) 10px, rgba(255,0,0,0.1) 20px), linear-gradient(white, white);
}
#inner {
height: 200px;
width: 400px;
background: darkgreen;
mix-blend-mode: hue;
}
<div id="container">
<div id="inner"></div>
</div>
If you add borders, margin, or padding, or the element adapts to the size of its content, though, this calculation will be incorrect.
Conclusion
In conclusion, everything is jank.
In my opinion, you'd be better off not fighting with CSS and JavaScript to coerce the value from the available information, and working out a way to do without the value. I've tried to do this kind of thing many times, so be forewarned: this way lies madness.
1RegEx lookbehinds are not even remotely close to being fully supported, so shouldn't be used in production.
You could read the stylesheet rule itself. If you know the selector that sets an elements width/height you can do this:
.box {
width: 12vw;
background: red;
}
<div class="box">red</div>
var sheet = document.styleSheets[0];
var rules = sheet.rules;
for (var i = 0; i < rules.length; i++) {
if (rules[i].selectorText == '.box') {
console.log(rules[i].style.width);
}
}
This will give you the 12vw you're looking for.
Depending on how your elements are defined, you could in theory create a helper function that gets these values for you by looping through the elements classList.
I have a slideshow on my landing screen that I want it to be fullscreen combined with a 70px height nav bar, I am trying to use sass so that I don't have to write javascript code for this, but
.slideshow{height:100vh-70px}
doesn't work. I don't know how sass calculates it, the CSS turns out to be
.slideshow{height:99.27083vh}
I did a quick search against this issue but couldn't find any useful information. So is this doable at all?
And if no, is there anyway to do it without javascript?
Try using CSS calc. It's pretty widely supported.
.slideshow {
height: calc( 100vh - 70px );
}
No, it isn't.
SASS calculations are performed when the SASS is compiled down to CSS.
The height of the viewport isn't known until the page is loaded into the browser. So you can't take that height, convert it to pixels, and do calculations with it.
I think it's just a space issue
just add space before and after the operator and put it between round brackets, it will work.
.slideshow {
height:(100vh - 70px);
}
The height on css it us used like this below:
height: auto|length|%|initial|inherit;
However, each of these should represent by numbers of px or etc. And the description for each value as following:
auto:(default) The browser calculates the height.
length:Defines the height in px, cm, etc.
%:Defines the height in percent of the containing block.
initial:Specifies that the value of the property should be set to the default value.
inherit:Specifies that the value of the property should be inherited from the parent element.
Example to set the height and width for a paragraph is like this:
P {height: 100px;
Width:100px;}
alert("Wrong (red): " + document.getElementById("target").getBoundingClientRect().top);
alert("Correct (blue): " + document.getElementById("wrapper").getBoundingClientRect().top);
#target {
transform: translate(20px, -20px) rotateZ(20deg);
background: red;
width: 50px;
height: 50px;
}
#wrapper {
background: blue;
display: inline-block;
}
Text
<div id="wrapper">
<div id="target">
</div>
</div>
further text
In the example above, the blue square has the exact position, the red one would have, if it had no transform. It has also exactly the space and position that the red square consumes, as an in-flow element. The position I want to get in JavaScript is the position of the blue square. My only problem is, that in my original code, there is no #wrapper and I am not able to create one. So how do I get the in-flow position of an element that might or might not be on that position (due to transform, position: relative; or others - if there are)?
Plain JS or jQuery solutions are both welcome. But I search for a rather simple/short solution, not some 50+ lines monster.
My attempts:
jQuery('#target').offset(): Takes transform into account (returns some negative number in the above example).
document.getElementById('target').getBoundingClientRect(): Same as jQuery's offset
jQuery('#target').position() with traversing through offsetParent: Might currently work, but jQuery's behavior in this regard is considered a bug or at least subject to coming changes, according to this site (if I interpret that site correctly).
Use WebKitCSSMatrix
var node = document.getElementById("target");
var curTransform = new WebKitCSSMatrix(window.getComputedStyle(node).webkitTransform);
console.log(node.offsetLeft + curTransform.m41); //real offset left
console.log(node.offsetTop + curTransform.m42); //real offset top
Browser Compatibility :
Check this answer to know how to handle browsers that isn't support WebKitCSSMatrix
I have two divs nested inside of a div.
<div id='outter' class='one'>
<div id='inner'></div>
<div id='button' class='bttn'>Click me!</div>
</div>
The outter div's height is a percentage of the page. I'd like one of the inside div's height to be a fixed difference away the outter div (i.e. $('#inner').height($('#outter').height() - 35)), because the second inner div is essentially a button with fixed height (35). I'd like this to happen even when I change the height (through CSS triggers (:hover/adding a class/etc. so I can use Transitions) or otherwise).
I googled around a bit and saw Less might be an answer, but from what I can tell it compiles in to static values, but I still need to use percentages, since I want this app to work/feel the same on any screen size.
I have examples of what I'm currently doing/how I'm thinking about it in some jsfiddles.
Current 'solution': http://jsfiddle.net/L9NVj/5/ (End heights are what I want them to be, but the transition looks terrible)
Idealistic 'solution': http://jsfiddle.net/L9NVj/6/ (End heights are wrong, but the inner div hugs appropriately)
Potential solution: http://jsfiddle.net/L9NVj/7/ (This hides the inner div on click and then shows it again when the appropriate size has been reached)
Any help/thoughts/insights would be greatly appreciated!
Consider absolute-positioning the inner elements, since the outer's size isn't controlled by their size/position.
#inner {
position: absolute;
top: 2px;
left: 2px;
right: 2px;
bottom: 35px;
/* ... */
}
.bttn {
position: absolute;
bottom: 2px;
left: 2px;
/* ... */
}
Example: http://jsfiddle.net/L9NVj/9/
How about conflicting absolute positioning. To do it, you'd just need to set the top, bottom, left and right of the #inner element and then transition those. That will maintain the distances around the edges of the element, and allow other positioning as well.
Note that while you don't need to actually calculate the value in this case, in the future, calc() can be used to calculate a dynamic value in CSS. In that case, you could do something like height: calc(100% - 37px); to get the same effect.
CSS3's calc() is the answer you're looking for, in combination with a JavaScript fallback for browsers that don't support calc(). In your 'Idealistic solution' fiddle, change your CSS height definition to the following:
height: -webkit-calc(100% - 35px);
height: calc(100% - 35px);
While normally you should include all prefixes (and you still may need to, depending upon your level of browser support), according to Can I Use, the only browsers that currently need prefixing are -webkit browsers.
What I would do with this knowledge is the following: grab a feature detection script, I really like Modernizr and detect to see if calc() is available in the browser. Modernizr has a non-core detect for calc() that you can use. Use that CSS in your CSS file as the default, then using a resource loader such as yepnope (comes with Modernizr), load in a JS solution if calc() isn't available.
Of your JavaScript solutions, I'd probably suggest your "Potential Solution" option, but instead of jQuery's hide() and show(), set opacity to 0 and 1 and use a CSS3 transition to transition between the two. I'd also not rely upon a timeout, but rather use the transitionend JavaScript event.
I edited your first jsfiddle little bit i think that's what you wanted. Just added line.
$(window).resize(function(){$('#inner').height($('#outter').height() - 35)});
jsfiddle:http://jsfiddle.net/Qqb3g/
You may have to some workaround to make transition smooth when button the button is clicked.
you need to calculate the inner div in %, so it can resize belong outer div, change your js code to this :
//calculating inner div'x height in % of outer
$('#inner').height((100 - (33/$('#outter').height() * 100)) + '%');
$('#button').click(function () {
$('#outter').toggleClass('two');
});
give a try to DEMO