I have a div inside another div with transform scale applied.
I need to get the width of this div after the scale has been applied. The result of .width() is the original width of the element.
Please see this codepen:
https://codepen.io/anon/pen/ZMpBMP
Image of problem:
Hope this is clear enough, thank you. Code below:
HTML
<div class="outer">
<div class="inner">
</div>
</div>
CSS
.outer {
height: 250px;
width: 250px;
background-color: red;
position: relative;
overflow: hidden;
}
.inner {
background-color: green;
height: 10px;
width: 10px;
transform: translate(-50%);
position: absolute;
top: 50%;
left: 50%;
transform: scale(13.0);
}
JS
$(function() {
var width = $('.inner').width();
// I expect 130px but it returns 10px
//
// I.e. It ignores the zoom/scale
// when considering the width
console.log( width );
});
Use getBoundingClientRect()
$(function() {
var width = $('.inner')[0].getBoundingClientRect();
// I expect 130px but it returns 10px
//
// I.e. It ignores the zoom/scale
// when considering the width
console.log(width.width);
});
https://jsfiddle.net/3aezfvup/3/
i achieved your 130 by this
var x = document. getElementsByClassName('inner');
var v = x.getBoundingClientRect();
width = v.width;
You need the calculated value. This can be done in CSS.
Use calc() to calculate the width of a <div> element which could be any elements:
#div1 {
position: absolute;
left: 50px;
width: calc(100% - 100px);
border: 1px solid black;
background-color: yellow;
padding: 5px;
text-align: center;
}
I found this about this topic.
Can i use Calc inside Transform:Scale function in CSS?
For JS:
How do I retrieve an HTML element's actual width and height?
Related
I'm facing problem with breaking the line on website. What do I mean?
HTML code
<main class="clearfix">
<div class="first"></div>
<div class="second"></div>
<div class="third"></div>
</main>
<button>Add</button>
With such HTML code I'd like to have:
fixed height on main element (for example 80vh)
fixed height for all the elements first and third 40vh + second 80vh
fixed width for first and third element 50vw
fluid width for second element - but this is main problem - second element has to be in the same place and grow horizontally (to create scroll on the bottom of the site)
Please find my codepen
I've added button that'll add pixels to second element - but it destroys my website.
I'm not sure if flexbox is better than floats.
I'll appreciate any tip.
Here is the snippet:
let counter = 0;
document.querySelector("button").addEventListener("click", function() {
document.querySelector(".second").style.width = `calc(50% + ${counter}px)`;
console.log(counter);
counter++;
});
* {
padding: 0;
margin: 0;
}
main {
max-height: 80vh;
}
.first,
.third {
height: 40vh;
width: 50vw;
background-color: black;
float: left;
}
.third {
background-color: red;
}
.second {
height: 80vh;
width: 50%;
float: right;
background-color: blue;
}
.clearfix::after {
content: "";
display: table;
clear: both;
}
<main class="clearfix">
<div class="first"></div>
<div class="second"></div>
<div class="third"></div>
</main>
<button>Add</button>
I would suggest you to go with position properties. Since you have a little difference between the order of your DOM element and their visual representation, like 1,2,3 in the DOM, but visually it's more like 1,3,2.
However, in such situation float is your enemy. I'm not 100% sure about flex, AFAIK flex would keep all the elements inside the parent element and prevent the scrolling.
If you go with absolute positioning, (since you already have the heights and widths defined)
Apply:
position: relative to the main element, it will be the base point of the child elements if they are set to absolute.
overflow-x: scroll to the main element. it will allow you to scroll horizontally when you increase the width of your second element.
position: absolute on .first, .second, .third, as you have the height and width defined, now set their position accordingly, check the snippet, you'll get it.
Finally you're good to add more value to your width of the target element.
Tip: always keep a consistency in your css units, for example, if used vh / vw use this for similar elements at least, or if px / em / rem is used, try to use the same accordingly.
Check the snippet in full page mode
let counter = 0;
document.querySelector("button").addEventListener("click", function() {
document.querySelector(".second").style.width = `calc(50vw + ${counter}vw)`;
document.querySelector("#added").textContent = counter;
counter++;
});
* {
padding: 0;
margin: 0;
}
main {
overflow-x: scroll;
position: relative;
min-height: 80vh;
}
.first,
.third {
height: 40vh;
width: 50vw;
background-color: black;
position: absolute;
left: 0;
top: 0;
}
.third {
background-color: red;
top: 40vh;
}
.second {
height: 80vh;
width: 50vw;
background-color: blue;
position: absolute;
left: 50vw;
top: 0;
}
button {
margin: 30px 5px;
border: 1px solid #cecece;
padding: 5px 10px;
}
<main>
<div class="first"></div>
<div class="second"></div>
<div class="third"></div>
</main>
<button>Add</button>
<p><span id="added">0</span>vw Added to blue div's width</p>
I had a problem:
Element overlapped element because it has a higher z-index (10 vs 5). Element has the child elements #sub-block-1 & #sub-block-2, and #sub-block-1 had child text #text1 with z-index = 20. But #text1 with z-index = 20 still under with z-index = 10. Why?
Tell me, how can I solve this problem?
The must have a predefined z-index (number, not 'auto', and less than z-index , for example, 5 vs 10).
My example:
https://jsfiddle.net/nynsjv3L/1/
P.S.
The above example is not displayed correctly in jsfiddle - the position of the elements (#sub-block-1 & #sub-block-2) does not work.
body {
background: #00ff00;
}
.screen {
position: absolute;
left: 0px;
top: 0px;
width: 100vw;
height: 100vh;
background: #ffffff;
opacity: 0.75;
z-index: 10;
}
#main-block {
position: absolute;
left: 500px;
top: 200px;
width: 700px;
height: 400px;
border: 2px solid #bb0000;
background: #ff0000;
z-index: 5;
}
.sub-block {
position: absolute;
width: 300px;
height: 150px;
background: #ffffff;
border: 4px solid #000000;
}
#sub-block-1 {
left: 100;
top: 100;
z-index: auto;
}
#sub-block-2 {
left: 275;
top: 175;
z-index: 11;
}
#text1 {
position: absolute;
left: 65px;
top: 55px;
color: #000000;
background: #ffff00;
font-size: 30px;
font-weight: 700;
z-index: 20;
}
#text2 {
position: absolute;
left: 65px;
top: 55px;
color: #00bbbb;
font-size: 30px;
font-weight: 700;
}
<div id='main-block'>
<div class='sub-block' id='sub-block-1'>
<div id='text1'>TEST TEXT</div>
</div>
<div class='sub-block' id='sub-block-2'>
<div id='text2'>NEW TEXT</div>
</div>
</div>
<div class='screen'></div>
The #text is still inside your block, that has a lower index than its sibling. The #text part is still in the same context block of its parent. You could check out the inner workings of z-indexes in this page.
You need to create a new stacking context for the text to appear above the other block. One of the possible ways is to change the opacity of the text to .99, or using the transform attribute. I do not recommend you to do it, though, as it will cause more troubles in the future.
Z-indexes should not be used very often. It is better to organize this inside the HTML itself. You should rethink your work.
#main-block is on the same level as .screen and has a lower z-index. So child elements of #main-block will always be overlapped by .screen and its children.
Whenever you set an element to be position: relative or position: absolute you open up a new z-index-stack for all of its children.
You either have to move the child elements of #main-block some levels up to make them independent or give the #main-block a higher z-index which will also result in overlapping .screen.
Hint: Negative z-index is also possible. And clean up your markup (keyword: single quotes). ;-)
I have a problem...In the following example i don't want that the div who is fixed get over the div with the background red.
Here is the example:
http://jsfiddle.net/HFjU6/3645/
#fixedContainer
{
background-color:#ddd;
position: fixed;
width: 200px;
height: 100px;
left: 50%;
top: 0%;
margin-left: -100px; /*half the width*/
}
Alright, I think I get what the OP wants. He wanted a container that stays fixed on the top of the viewport, but remains confined by a parent. This behaviour is known as a conditional sticky behaviour, and is actually implemented in both Firefox (without vendor prefix) and macOS/iOS Safari (with -webkit- prefix): see position: sticky.
Therefore the easiest (but also the least cross-browser compatible) way is simply to modify your markup, such that the sticky element stays within a parent, and you declare position: sticky on it:
* {
margin: 0;
padding: 0;
}
#fixedContainer {
background-color: #ddd;
position: -webkit-sticky;
position: sticky;
width: 200px;
height: 100px;
left: 50%;
top: 0%;
transform: translate(-50%, 0); /* Negative left margins do not work with sticky */
}
#div1 {
height: 200px;
background-color: #bbb;
}
#div1 .content {
position: relative;
top: -100px; /* Top offset must be manually calculated */
}
#div2 {
height: 500px;
background-color: red;
}
<div id="div1">
<div id="fixedContainer">I am a sticky container that stays within the sticky parent</div>
<div class="content">Sticky parent</div></div>
<div id="div2">Just another element</div>
An alternative would be to use a JS-based solution. In this case, you do not actually have to modify your markup. I have changed the IDs for easier identification of the elements, however.
The gist of the logic is this:
When the scroll position does not exceed the bottom of the parent minus the outer height of the sticky content, then we do not do anything.
When the scroll position exceeds the bottom of the parent minus the outer height of the sticky content, we dynamically calculate the top position of the sticky content so that it remains visually in the parent.
$(function() {
$(window).scroll(function() {
var $c = $('#sticky-container'),
$s = $('#sticky-content'),
$t = $(this); // Short reference to window object
if ($t.scrollTop() > $c.outerHeight() - $s.outerHeight()) {
$s.css('top', $c.offset().top + $c.outerHeight() - $t.scrollTop() - $s.outerHeight());
} else {
$s.css('top', 0);
}
});
});
* {
margin: 0;
padding: 0;
}
div {
height: 500px;
background-color: red;
}
#sticky-container {
background-color: #bbb;
height: 200px;
}
#sticky-content {
background-color: #ddd;
position: fixed;
width: 200px;
height: 100px;
margin-left: -100px;
left: 50%;
top: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="sticky-content">Sticky content that stays within the bounds of #div1</div>
<div id="sticky-container">Sticky confinement area</div>
<div>Other content</div>
Old answer before OP clarified the question appropriately:
Just give them the appropriate z-index values. In this case, you want to:
Do not use static positioning. This can be done by using position: relative for the large elements, in conjunction with the originally position: fixed element.
Assign the appropriate stacking order. The grey <div> element to have the lowest z-index, followed by the position fixed element, and then by the red element.
There are some catchalls to stacking though: the stacking context is reset when you traverse up or down the node tree. For example, the example will not work if the elements are not siblings.
Here is a proof-of-concept example, modified from your fiddle so that inline CSS is removed.
* {
margin: 0;
padding: 0;
}
#fixedContainer {
background-color: #ddd;
position: fixed;
width: 200px;
height: 100px;
left: 50%;
top: 0%;
margin-left: -100px;
z-index: 2;
}
#div1 {
height: 200px;
background-color: #bbb;
position: relative;
z-index: 1;
}
#div2 {
height: 500px;
background-color: red;
position: relative;
z-index: 3;
}
<div id="fixedContainer">z-index: 2</div>
<div id="div1">z-index: 1</div>
<div id="div2">z-index: 3</div>
Just give the z-index.
Hope it helps...
http://jsfiddle.net/HFjU6/1/#run
#fixedContainer {
background-color:#ddd;
position: fixed;
width: 200px;
height: 100px;
left: 50%;
top: 0%;
margin-left: -100px; /*half the width*/
z-index: 2;
}
.div-red {
position: relative;
z-index: 5;
}
<div id="fixedContainer"></div>
<div style="height:200px;background-color:#bbb;"></div>
<div style="height:500px;background-color:red;" class="div-red"></div>
I am struggling all afternoon to resolve a problem. Maybe this is a common question but I could not find anything similar in here or on Google. I hope you guys can help.
I have a fixed positioned element on the left of the page and I want that the distance between that element and another on the page be always the same when the browser window is larger. How can I do it?
Now, the other element has to be set in percentage while the fixed element can be or not with pixels.
Is there any css calc(), javaScript, jQuery, something you can think of to resolve this?
HTML
<div class="fixed"></div>
<div class="left-element"></div>
CSS
body {
margin: 0;
padding: 0;
border: 1px solid black;
min-height: 2000px;
min-width: 100%;
}
.fixed
{
position: fixed;
top: 0;
left: 0;
height: 200px;
width: 200px;
background-color: blue;
}
.right-element {
width: 25%;
height: 200px;
background-color: yellow;
margin-left: 75%;
}
Here is the Fiddle
I have the same solution as #Calvin Claus but with just a minor css modifcation, no javascript needed
.right-element {
width: calc(100% - 400px);
height: 200px;
background-color: yellow;
margin-left: 400px;
}
fiddle
Update: Similar, but as you asked, the calc on the fixed element.
.fixed {
position: fixed;
top: 0;
left: 0;
height: 200px;
width: calc(75% - 200px);
background-color: blue;
}
.right-element {
width: 25%;
height: 200px;
background-color: yellow;
margin-left: 75%;
}
new fiddle
I came up with a simple jquery solution:
var distanceBetwennElems = 100;
function calcRightElemWidth() {
var rightElemWidth = $(window).width() - ($('.fixed').width() + distanceBetwennElems);
$('.right-element').css("width", rightElemWidth);
}
Just call this when the document is ready and the window is resized.
Also I removed margin and width form the .right-element css, because this is done by js now:
.right-element {
height: 200px;
background-color: yellow;
float: right;
}
https://jsfiddle.net/bjrno78p/2/
You can adjust the width of the left, fixed element, using calc. Here's an example using 500px as the desired distance between the elements, and 25% as the width for the right-element.
.fixed
{
// disired distance = 500px
// right-element width = 25%
width: calc(100vw - 500px - 25%);
}
Your updated fiddle
I have a canvas in my page, and i want it to fill the page until it reaches the bottom of the page.
I have the canvas' width set to 100%, but i cannot set the height to 100% as it extends too far.
The position of the div is not 0,0 of the browser window there are other things above it, so i end up with a scroll bar because 100% height extends well below the bottom of my browser's output.
So i was wondering how can i extend the element's height to reach the bottom of the page from its current position on the web page?
<style>
.canvas{
position:absolute;
width:100%;
height:100%;
}
<style>
<div class="logo">Stuff here</div>
<div class="output">
<canvas class="canvas"></canvas>
</div>
Do i need to use JavaScript or is there a CSS method to doing this?
If you know the height of the content above the canvas, you can use top and bottom properties to take up the rest of the space:
JS Fiddle
.logo {
height: 40px;
}
.output {
position: absolute;
top: 40px; // height of above content
bottom: 0;
width: 100%;
padding: 0;
}
.canvas {
position: absolute;
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
And if you don't know the height of the above content, you can calculate it:
JQuery Example: JS Fiddle
var height = $('header').height();
$('.output').css('top', height);
this technique is also great when making resizable popups with fixed height headers and footers, but fluid height content
https://jsfiddle.net/ca5tda6e/
set the header (.logo) to a fixed height
.logo{
height: 100px;
background-color: lightGray;
position: relative;
z-index: 1;
}
then position the content (.output) absolute, with a padding-top: 100px
.output{
width: 100%;
height: 100%;
box-sizing: border-box; /* so that padding is included in width/height */
padding-top: 100px; /* padding-top should be equal to .logo height */
position: absolute;
top: 0;
left: 0;
overflow: hidden; /* there was like a pixel of something i couldnt get rid of, could have been white space */
}
I've had this problem before, in CSS, create this rule....
html, body {
margin: 0;
}