Expand absolutely positioned width only if it overflows parent - javascript

I have a parent div(A) which is relatively positioned and there'll be two divs(X and Y) inside the parent div. Y is a small element and will be rendered on top of X so I've added position: absolute on Y. Y will also cover z% of its parent's size. There'll be more elements below parent div A.
Codepen link: https://codepen.io/shiva3/full/eYjXxxy
/* A element */
.parent {
position: relative;
height: 20em;
width: 40em;
}
/* X element */
.big {
width: 100%;
height: 100%;
}
/* Y Element */
.rectangle {
height: calc(100% - 2em);
width: 30%;
background-color: pink;
z-index: 2;
bottom: 0;
position: absolute;
}
This is the output
The issue I'm facing is, whenever Y has large content(or when we zoom in) it overflows and interferes with the element below it.
Overflown content
I want to change the width of the element only if Y overflows.

Create a id or a class to your paragraph in html
Just go in CSS and put max-height (like 250px seems good) and a overflow-y scroll

Related

How to anchor one div to another and keep them responsive

I have a UI built in vue.js that I need to add tooltips to. I need the tooltips to be placed to the left or right of a specific div in the UI. I've been able to get my desired look by setting the tooltips to position absolute but this is not responsive so on some screens the tooltip does not align with the target div.
The UI is fairly complex so I'm trying to avoid having to rebuild the layout with flexbox/grid. I'm looking for a way to 'anchor' the tooltip to its corresponding divs using javascript.
https://codepen.io/joeymorello/pen/ZEeWmGd Here I am playing with append to and insertBefore but I would still need to fine-tune each tooltip location using CSS. Is there a way to just anchor one div right next to another div so the tooltip always follows its parent div?
const head = document.querySelector('.head')
const body = document.querySelector('.body')
const toolTipOne = document.querySelector('.tool-tip-1')
const toolTipTwo = document.querySelector('.tool-tip-2')
$(toolTipOne).appendTo(head);
$(toolTipTwo).insertBefore(body);
Apply position: relative to .body and append the tooltip inside it. Then you can easily position it with absolute relative to position of .body using top, left etc:
https://codepen.io/tilwinjoy/pen/QWpNJdY
Why not use pure css for this? You can use position relative on the element, then use its pseudo ::after element and set its position to absolute. Then call on the left, top, right and/or bottom properties to place your pseudo element on the page relative to its parent that has position relative set.
// example of how to change the content of a pseudo tag with JS and CSS variables using the root element
let root = document.documentElement
let headTTInfo = 'Maybe you want to change the Head tooltips content via JS?'
let bodyTTInfo = 'Here is content for your body elements tool tip generated with JS.'
root.style.setProperty('--body', `"${bodyTTInfo}"`)
root.style.setProperty('--head', `"${headTTInfo}"`)
:root {
--head: 'this is content for your head elements tool tip';
--body: 'this is content for your body elements tool tip'
}
/* This min-width on the body will ensure that your absolutely positioned element
is within the body and its display is not completely taken out of the
viewable container,
125px(tooltip offset) + 500px(width of parents) + 125px(tooltip offset) = 750
gives us 10px padding on each side if screen width less than the width of the
parents elements, we do this because postion absolute takes its positioned elements
out of the normal flow of the document. */
body {
min-width: 770px;
}
.head {
margin: 0 auto;
width: 500px;
height: 250px;
background-color: green;
position: relative;
}
.body {
margin: 1rem auto;
width: 500px;
height: 250px;
background-color: pink;
position: relative;
}
.head::after {
content: var(--head);
position: absolute;
left: -125px;
top: 40%;
width: 100px;
height: auto;
padding: 5px;
background-color: teal;
}
.body::after {
content: var(--body);
position: absolute;
left: 515px;
top: 40%;
width: 100px;
height: auto;
padding: 5px;
background-color: orange;
}
<div class="container">
<div class="head">HEAD</div>
<div class="body">body</div>
</div>

Calculate required height to make scaled down div reach the bottom viewport

I'm using CSS transform: scale(0.6) to scale down a div. When the element is scaled down, it maintains its aspect ratio. However, in my case, this element needs to always have a height that will reach the bottom of the viewport. This means I need to adjust the height of the element while keeping its width and top position the same.
How do I calculate the height I need to apply so that the element reaches the bottom of the viewport exactly when transform: scale(x) is applied?
below is a codesnippet. Clicking anywhere scales the div down and it's when I should apply the new height to allow the div height to reach the bottom of the viewport while keeping the same width, and position.
document.body.addEventListener('click', () => {
document.querySelectorAll('div')[0].style.transform = 'scale(0.44)';
});
body {
margin: 0;
padding: 0;
height: 100vh;
}
div {
width: 350px;
height: calc(100% - 50px);
position: absolute;
top: 50px;
background-color: red;
position: absolute;
transform-origin: top;
}
<div><h1>TEST</h1></div>
Since you want the div's height to stretch till bottom, you can make use of window.innerHeight here.
The new height can be calculated using the following formula :-
newHeight = (viewportHeight - offsetTop)*(1/scaleValue)
Putting in values it will come down to the following calculation :-
newHeight = (window.innerHeight - div.offsetTop)*(1/0.44)
document.body.addEventListener('click', () => {
const div = document.querySelectorAll('div')[0];
div.style.transform = 'scale(0.44)';
div.style.height = `${(window.innerHeight-div.offsetTop)*(1/0.44)}px`
});
body {
margin: 0;
padding: 0;
height: 100vh;
}
div {
width: 350px;
height: calc(100% - 50px);
position: absolute;
top: 50px;
background-color: red;
position: absolute;
transform-origin: top;
}
<div>
<h1>TEST</h1>
</div>
i see you position it from the top. i think that if you position it from bottom you will get what u want.
change top to bottom: 0px
change tranform-origin to transform-origin:bottom
and for calculating the height u could use 100VH instead of 100%

How can I stretch an absolute div to the width of it's grandparent while inside an absolute parent div

My html/css is structured like this:
<div class="grandparent">
<div class="row">...</div>
<div class="absolute-parent">
<div class="absolute-child">...</div>
</div>
</div>
.grandparent {
position: relative;
}
.absolute-parent {
width: *gets set by JS*
height: 30px;
position: absolute;
top: 0;
bottom: 0;
left: *gets set by JS*
overflow: hidden;
margin: 0 auto;
transition: all 0.5s ease-in-out;
}
.absolute-child{
align-items: center;
display: flex;
flex-direction: row;
justify-content: center;
bottom: 0;
position: absolute;
top: 0;
left: *gets set by JS*
margin: auto 0;
transition: left 0.5s ease-in-out;
}
.absolute-parent has a fixed height while width and left position get set by javascript depending on the position of a selected element in .row div, it serves as window to absolute-child's content which should be layered with .row-div" content.
Right now .absolute-child only stretches as wide as the content inside of it, I'd like to make it stretch the whole container width of .grandparent div so .absolute-child and .row are right on top of one another.
Cheers !
The only way I can think of, is making the parent div inherit the with of the grand-parent, and making the child inherit the width of the parent. But, the grand parent needs to have a set width for that. Or just setting manually the width of all those divs. It may not be the answer you are expecting, but that is the method I have been using in such situations for a long time.
Since an absolutely positioned element refers to its next higher relatively positioned ancestor for its position and size (if defined in percentage), it should work to simply add width: 100% to .absolute-child to make it as wide as the .grandparent element

How i can make div cover the object tag on html for IE11?

How can I make div cover the object tag on HTML for IE11, object tag is activeX for IE.
I want to make div layer cover the object tag.
The trick is to wrap your object tag in a container div. Set the dimensions of the activex component on the container and set the containers position to relative.
Drop another div - as a sibling to your activex component, and set its position to absolute. This will allow it to float/start at the start of the container (just like your activex) by setting its top to 0. Set this div's height and width to 100% to fill the whole container. Since your container has the same dimensions that your activex, this should cover it up.
#container {
position: relative;
height: 200px;
width: 200px;
}
#object {
height: 200px; /* emulate the objectx height */
width: 200px; /* emulate the objectx width */
background-color: yellow;
}
#overlay {
height: 100%;
width: 100%;
background-color: green;
position: absolute;
top: 0;
}
<div id="container">
<div id="object"></div>
<div id="overlay"></div>
</div>
http://plnkr.co/edit/H405MbFN9a1wxzqXkYXz?p=preview
Play around with the Plunker to see what happens and learn how it works.

Absolutely position element based on center

A convenient way to make an absolutely-positioned hovering element that lets height vary with content using Javascript is to specify the width, top and left as style fields. For instance:
popup.style.width = foo.offsetWidth - 10 + 'px';
popup.style.top = document.getElementById(bar)
.getBoundingClientRect().top + 'px'; // for IE7, can't use offsetTop
popup.style.left = '15px';
How can I adapt this code to absolutely position the popup based on its center, rather than its top? I'd like to do popup.style.center instead of popup.style.top, but that's not how CSS works. A completely naive solution is to add it to the DOM, then measure its height, and subtract half the height from the top.
Alternatively, is there a completely different approach that would still allow setting an arbitrary position for each corner of the element?
I'm looking for a pure Javascript solution (e.g. no jquery).
Important: I'm not trying to center the popup inside another element. Rather, I want the center point of the popup to be specified as a pixel offset from the top of the screen. This pixel offset may be based on another element, or it may be a raw number.
In your important note you are dealing with two different notions:
The first one, offset from the top of the screen, can be achieved with position:fixed.
The second one, offset based on another element, is where absolute positioning is useful, and will be relative to the first position:relative parent element.
As suggest Table-Cell centering (thanks to Itay comment) it makes sense in your case to use table display because it's exactly its purpose: adapt the container to its content.
You need some extra html:
<div class="container">
<div class="popup">
<div class="content">
<!-- CONTENT -->
</div>
</div>
</div>
And apply this css:
.container {
position: absolute; /* or fixed */
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.popup {
display: table;
height: 100%;
}
.content {
display: table-cell;
vertical-align: middle;
}
Thanks to the table-cell display you can use vertical-align: middle, no more need of javascript.
For horizontal centering you can still add a classic width: 50%; margin: 0 auto; on popup class.
To do this in jquery would be pretty simple
DEMO jsFiddle
jQuery.fn.center = function(parent) {
if (parent) {
parent = this.parent();
} else {
parent = window;
}
this.css({
"position": "absolute",
"top": ((($(parent).height() - this.outerHeight()) / 2) + $(parent).scrollTop() + "px"),
"left": ((($(parent).width() - this.outerWidth()) / 2) + $(parent).scrollLeft() + "px")
});
return this;
}
$("div.target").center(true);
I had been thinking about this for a while. You can actually absolute position an element from the center of a container instead of the corners by adding a div inside the container. This inner container, or reference container, is 50% height and 50% width of the parent container. Then you can position relative to the bottom right corner.
HTML
<div class="container">
<div class="container-inner">
<div class="pointer pointer-1" data-name="pointer-1"></div>
<div class="pointer pointer-2" data-name="pointer-2"></div>
</div>
</div>
CSS
This is the container we want to place pointers in
html, body {
height: 100%;
}
.container {
height: 80%;
width: 80%;
margin: 0 auto;
border: 1px solid blue;
}
We use this container to get a center point that we can use as a reference. We use the bottom right corner of this div as our reference point.
.container-inner {
border: 1px dashed red;
height: 50%;
width: 50%;
position: relative;
}
Create a couple of targets 60px in diameter
.pointer {
height: 40px;
width: 40px;
background-color: orange;
border: 10px solid red;
border-radius: 60px;
position: absolute;
}
Center target one in the center of the container
.pointer-1 {
bottom: calc(-0% - 30px);
right: calc(-0% - 30px);
}
Position target 2 25% right and down from the container center.
.pointer-2 {
bottom: calc(-50% - 30px);
right: calc(-50% - 30px);
}
You can see a working demo of this JSBin.
Would this work?
.popup {
margin-top: -50%;
}
In the end, I decided to just add the element to the DOM, measure its height, and subtract half the height from the top. I make the element invisible before adding it, and visible again after adjusting the height, to avoid flickering.

Categories