How to set a dynamic CSS value with JavaScript - javascript

I want to have responsive padding for a div on my page.
It should be a fifth of the height of itself, which is in the variable cover_height.
This is my approach so far, which is following an answer to this question,
but it doesn't change padding-top:
var cover = document.getElementById("cover");
var cover_height = cover.height;
cover.style["padding-top"] = cover_height / 5 + "px";
Any feedback regarding the code is welcome as I am pretty new to JS.

JavaScript (vanilla) has no element.height function as far as I know. It should be .clientHeight or .offsetHeight depending on what you are looking for. offsetHeight returns the height including the border, padding and scroll bars.
var cover = document.getElementById("cover");
var cover_height = cover.clientHeight;
cover.style["padding-top"] = cover_height / 5 + "px";
#cover {
height: 300px;
background: red;
}
<div id='cover'></div>
Does this approach to responsive design make sense?
If you could use fixed viewport unit based value for height then I would recommend something like in the below snippet. Here the height of the element increases (or decreases) based on the height of the viewport and the padding-top is always 1/5th of the height. For example, if viewport height is 100px, the element's height would be 30px and the padding top would be 6px.
#cover {
height: 30vh;
background: red;
padding-top: 6vh;
}
<div id='cover'></div>
If you cannot use viewport units (or) the element's height is auto and will increase or decrease based on content then your approach is reasonably good for setting padding-top.
If you had wanted to set padding-top based on the width of the element's parent then I would have recommended doing it with pure CSS using percentage values. This is because a percentage value for padding or margin is always computed with respect to the element's width. An exampe of this behavior is available here.

Working fiddle
You should use clientHeight or offsetHeight instead of height.
clientHeight : includes the height and vertical padding.
offsetHeight : includes the height, vertical padding, and vertical borders.
Example :
var cover = document.getElementById("cover");
var cover_height = cover.clientHeight;
//OR
var cover_height = cover.offsetHeight;
cover.style.paddingTop = cover_height / 5 + "px";
Hope this helps.
var cover = document.getElementById("cover");
var cover_height = cover.clientHeight;
cover.style.paddingTop = cover_height / 5 + "px";
#cover{
width: 200px;
height: 200px;
background-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='cover'> Cover </div>

Related

Convert vh units to px in JS

Unfortunately 100vh is not always the same as 100% browser height as can be shown in the following example.
html,
body {
height: 100%;
}
body {
overflow: scroll;
}
.vh {
background-color: blue;
float: left;
height: 50vh;
width: 100px;
}
.pc {
background-color: green;
float: left;
height: 50%;
width: 100px;
}
<div class="vh"></div>
<div class="pc"></div>
The issue is more pronounced on iPhone 6+ with how the upper location bar and lower navigation bar expand and contract on scroll, but are not included in the calculation for 100vh.
The actual value of 100% height can be acquired by using window.innerHeight in JS.
Is there a convenient way to calculate the current conversion of 100vh to pixels in JS?
I'm trying to avoid needing to generate dummy elements with inline styles just to calculate 100vh.
For purposes of this question, assume a hostile environment where max-width or max-height may be producing incorrect values, and there isn't an existing element with 100vh anywhere on the page. Basically, assume that anything that can go wrong has with the exception of native browser functions, which are guaranteed to be clean.
The best I've come up with so far is:
function vh() {
var div,
h;
div = document.createElement('div');
div.style.height = '100vh';
div.style.maxHeight = 'none';
div.style.boxSizing = 'content-box';
document.body.appendChild(div);
h = div.clientHeight;
document.body.removeChild(div);
return h;
}
but it seems far too verbose for calculating the current value for 100vh, and I'm not sure if there are other issues with it.
How about:
function viewportToPixels(value) {
var parts = value.match(/([0-9\.]+)(vh|vw)/)
var q = Number(parts[1])
var side = window[['innerHeight', 'innerWidth'][['vh', 'vw'].indexOf(parts[2])]]
return side * (q/100)
}
Usage:
viewportToPixels('100vh') // window.innerHeight
viewportToPixels('50vw') // window.innerWidth / 2
The difference comes from the scrollbar scrollbar.
You'll need to add the height of the scrollbar to the window.innerHeight. There doesn't seem to be a super solid way of doing this, per this other question:
Getting scroll bar width using JavaScript

Javascript positioning center style

I wanted to set my second div element indside of my first div element center. I think somehow I managed to center it. But I think I made some mistakes and it seems to me it is not properly centered and also this JavaScript style seems to me bad. Is there any better way doing it? Is my JavaScript code is correct?
FIDDLE
HTML
<div class='first'>
<div class='second'>
</div>
</div>
JavaScript
var first = document.getElementsByClassName('first')[0];
var second = document.getElementsByClassName('second')[0];
var height = first.offsetHeight;
second.style.width = height/2+"px";
second.style.height = height/2+"px";
second.style.marginLeft = height/4+"px";
second.style.marginTop = height/4+"px";
offsetHeight will get the height of the element including borders, clientHeight won't. Instead of:
var height = first.offsetHeight;
Try:
var height = first.clientHeight;
JSFiddle
I've also used top and left with position:absolute for positioning, as this take the element out of the page flow and I assume this is the behaviour you are looking for.
References:
offsetHeight
clientHeight
(Follow the links and take a look at the box-model diagrams)
Reason is drawing round take 3px thats why not positioning but you divide 2.1 that result come that you need.
Check this Demo jsFiddle
JavaScript
var first = document.getElementsByClassName('first')[0];
var second = document.getElementsByClassName('second')[0];
var height = first.offsetHeight;
second.style.width = height/2.1+"px";
second.style.height = height/2.1+"px";
second.style.marginLeft = height/4+"px";
second.style.marginTop = height/4+"px";
var second = document.getElementsByClassName('second')[0];`
var left = (screen.width/2)-(100/2);
var top = (screen.height/2)-(100/2);
second.style.width = "100px"; //set as per your requirement
second.style.height = "100px"; //set as per your requirement
second.style.left= left +"px";
second.style.top = top +"px";
Just in case, you're interested, I tried to come up with a CSS only solution.
http://jsfiddle.net/53M6A/1/
Here's the changes I made to the .second class.
.second{
left: 50%; //move 50% to left
top: 50%; // move 50% down
margin-left: -50px; //move half of it's own size back to the left
margin-top: -50px; //move half of it's own size back to the top
position: relative; //make it relative, so it can be moved around by left/top
width:100px;
height:100px;
background: #fff;
border-radius:50%;
}
I've been playing a little in your fiddle and finally, I changed your 2 last lines for these:
first.style.display = "table-cell";
first.style.verticalAlign = "middle";
second.style.margin = "0 auto";
Fiddle
Seems perfectly centered to me.

How do you reduce the scrollable height of a div with scaled content?

I have a scrollable div that I zoom/scale the content of using css3 transform. It works fine if I'm zooming in (scaling up the content) but I've noticed that when scaling down, below 100%, the amount that you can scroll vertically of the container div does not reduce.
I've made a jsfiddle to illustrate this
CSS:
.scrollable
{
height: 250px;
width: 250px;
overflow: auto;
background-color: green;
}
.content
{
height :500px;
width : 500px;
background: linear-gradient(red, blue);
...
}
JS/jquery:
function scaleContent(newScale){
var $content = $("#content");
var scaleString = "scale("+newScale+")";
//var height = (newScale<1)? $("#content").height()/scale*newScale : originalHeight;
$content.css({
'-webkit-transform' : scaleString,
'-webkit-transform-origin' : '0 0',
...
//'height' : height +'px'
});
scale=newScale;
}
The actual scaling and the amount that you can scroll horizontally works perfectly, but the amount you can scroll vertically doesn't change below 100%.
Note: the amount you can scroll vertically appears to change on the first scaledown/zoomout, but this is simply because the horizontal scrollbar is removed.
I tried to manually change the height of the content, but this just messed with the content dimensions (duh). That's the commented-out height code.
The ellipses are where I've repeated things for other browsers.
I've managed to come up with one solution, though it's probably not the best. I introduced another div around the content, which I call the view wrapper. I set its overflow to "hidden" and manually set its width and height to match what the scaled content should be.
CSS:
.viewwrapper{
height :500px;
width : 500px;
overflow: hidden
}
JS:
function scaleContent(newScale){
var $content = $("#content");
var scaleString = "scale("+newScale+")";
var $viewwrapper = $("#viewwrapper");
var height = $content.height()/newScale;
var width = $content.width()/newScale;
$viewwrapper.height(height);
$viewwrapper.width(width);
$content.css({
'-webkit-transform' : scaleString,
'-webkit-transform-origin' : '0 0',
...
});
}
JS Fiddle
Update:
This won't work if you're using jQuery 3.0 or 3.1. The read behaviour of the height and width functions has changed, so they return the scaled values. To fix the above code for those versions you can just say.
function scaleContent(newScale){
var $content = $("#content");
var scaleString = "scale("+newScale+")";
var $viewwrapper = $("#viewwrapper");
$viewwrapper.height($content.height());
$viewwrapper.width($content.width());
$content.css({
'-webkit-transform' : scaleString,
'-webkit-transform-origin' : '0 0',
...
});
}
JSFiddle using jQuery 3.0
However this probably won't make it into future versions of jQuery.
Update 2:
You might see unnecessary scrollbars in Chrome when you zoom out of the content. This is down to a Chrome bug.
you're applying transformations to your #content div, but the outside div, #scrollable has also a fixed height and is not reducing. You have to apply transformations to it too.
Because if you're zooming in, the outside div adapts to the inside content, whereas if you're reducing it does not.

jQuery - Margin left minus half of the div's width

I want to achieve something like this:
I have a div, which width is not specified, so it changes basing on the content it has. First of all, I want to calculate that div's width. After that, I would like to add css style with jquery, which will margin that div left half of its width. So, if the div's width is 300px, I want this css added to the same div:
margin-left: -150px;
I hope I was clear. Thanks a lot.
use this code:
// get div width
var width = $('div').width();
// calculate margin size
var marginLeft = width / 2;
// set css
$('div').css('margin-left', -marginLeft);
var w = $("#left-shunted-div").width();
var left_mar = -(w/2);
$("#left-shunted-div").css("margin-left",left_mar);
You could simply do it like so:
// After dom load
$(function(){
// Select the div
var div = $('#myDiv');
// Get the width;
var width = div.outerWidth();
// Change the margin-left to half negative
div.css({'marginLeft' : -(width / 2) + 'px'});
});

How to reliably get screen width WITH the scrollbar

Is there a way to reliably tell a browser's viewport width that includes the scrollbar, but not the rest of browser window)?
None of the properties listed here tell me the width of the screen INCLUDING the scrollbar (if present)
I figured out how to accurately get the viewport width WITH the scrollbar using some code from: http://andylangton.co.uk/blog/development/get-viewport-size-width-and-height-javascript
Put this inside your $(document).ready(function()
$(document).ready(function(){
$(window).on("resize", function(){
function viewport() {
var e = window, a = 'inner';
if (!('innerWidth' in window )) {
a = 'client';
e = document.documentElement || document.body;
}
return { width : e[ a+'Width' ] , height : e[ a+'Height' ] };
}
});
// Get the correct window sizes with these declarations
windowHeight = viewport().height;
windowWidth = viewport().width;
});
What it Does:
When your page is 'ready' or is resized, the function calculates the correct window height and width (including scrollbar).
I assume you want to know the viewport width with scrollbar included, because the screen it self does not have a scrollbar. In fact the Screen width and heigth will be the computer screen resolution itself, so I'm not sure what you mean with screen width with the scroll bar.
The viewport however, the area where only the page (and scroll bars) is presented to the user, meaning, no browser menus, no bookmarks or whatever, only the page rendered, is where such scroll bar may be present.
Assuming you want that, you can measure the client browser viewport size while taking into account the size of the scroll bars this way.
First don't forget to set you body tag to be 100% width and height just to make sure the measurement is accurate.
body {
width: 100%;
// if you wish to also measure the height don't forget to also set it to 100% just like this one.
}
Afterwards you can measure the width at will.
Sample
// First you forcibly request the scroll bars to be shown regardless if you they will be needed or not.
$('body').css('overflow', 'scroll');
// Viewport width with scroll bar.
var widthWithScrollBars = $(window).width();
// Now if you wish to know how many pixels the scroll bar actually has
// Set the overflow css property to forcibly hide the scroll bar.
$('body').css('overflow', 'hidden');
// Viewport width without scroll bar.
var widthNoScrollBars = $(window).width();
// Scroll bar size for this particular client browser
var scrollbarWidth = widthWithScrollBars - widthNoScrollBars;
// Set the overflow css property back to whatever value it had before running this code. (default is auto)
$('body').css('overflow', 'auto');
Hope it helps.
As long as body is 100%, document.body.scrollWidth will work.
Demo: http://jsfiddle.net/ThinkingStiff/5j3bY/
HTML:
<div id="widths"></div>
CSS:
body, html
{
margin: 0;
padding: 0;
width: 100%;
}
div
{
height: 1500px;
}
Script:
var widths = 'viewport width (body.scrollWidth): '
+ document.body.scrollWidth + '<br />'
+ 'window.innerWidth: ' + window.innerWidth + '<br />';
document.getElementById( 'widths' ).innerHTML = widths;
I put a tall div in the demo to force a scroll bar.
Currently the new vw and vh css3 properties will show full size including scrollbar.
body {
width:100vw;
height:100vh;
}
There is some discussion online if this is a bug or not.
there is nothing after scrollbar so "rest of the window" is what?
But yes one way to do it is make another wrapper div in body where everything goes and body has overflow:none; height:100%; width:100%; on it, wrapper div also also has 100% width and height. and overflow to scroll. SO NOW...the width of wrapper would be the width of viewport
See Example: http://jsfiddle.net/techsin/8fvne9fz/
html,body {
height: 100%;
overflow: hidden;
}
.wrapper {
width: 100%;
height: 100%;
overflow: auto;
}
With jQuery you can calculate the browser's scrollbar width by getting the width difference when overflow: hidden is set and overflow: scroll is set.
The difference in width will be the size of the scrollbar.
Here is a simple example that shows how you could do this.
You can get the window width with scrollbar , that way:
function scrollbar_width() {
if (jQuery('body').height() > jQuery(window).height()) {
/* Modified from: http://jdsharp.us/jQuery/minute/calculate-scrollbar-width.php */
var calculation_content = jQuery('<div style="width:50px;height:50px;overflow:hidden;position:absolute;top:-200px;left:-200px;"><div style="height:100px;"></div>');
jQuery('body').append(calculation_content);
var width_one = jQuery('div', calculation_content).innerWidth();
calculation_content.css('overflow-y', 'scroll');
var width_two = jQuery('div', calculation_content).innerWidth();
jQuery(calculation_content).remove();
return (width_one - width_two);
}
return 0;
}
Check out vw: http://dev.w3.org/csswg/css-values/#viewport-relative-lengths
body {
width: 100vw;
}
http://caniuse.com/#search=vw
This is my solution for removing the 'scrollbar shadow', because scrollWidth didn't work for me:
canvas.width = element.offsetWidth;
canvas.height = element.offsetHeight;
canvas.width = element.offsetWidth;
canvas.height = element.offsetHeight;
It's easy, but it works. Make sure to add a comment explaining why you assign the same value twice :)

Categories