Absolute element moving away from image - css

Can I somehow make the absolute element stay at the same position all the time even when the parent(relative) image is adjusting its size to screen? At the moment I am using px to use position of elements, its fine on huge screen, but whenever the image gets smaller the absolute elements wont stick to the same position. Also I tried using <img></img> and put elements inside it and make the img as relative, but I think these tags dont work.
.img {
width: 100%;
height: auto;
}
.container {
position: relative;
}
.container > p {
position: absolute;
left: 300px;
bottom: 200px;
}
<div class="container">
<img src="https://pngimg.com/uploads/surfing/surfing_PNG9721.png" class="img">
<p>Im absolute
</p>
</div>

use percentage and for font-size use clamp()
.img {
width: 100%;
height: auto;
}
.container {
position: relative;
}
.container > p {
position: absolute;
left: 22%;
bottom: 48%;
color : white;
font-size: clamp(5px,2vw,3rem);
}
<div class="container">
<img src="https://pngimg.com/uploads/surfing/surfing_PNG9721.png" class="img">
<p>Im absolute
</p>
</div>

Try removing the "position: relative;" of the container. Your p tag is absolute respect the container because of that. Removing relative in container, the absolute is refered to the document.
.img {
width: 100%;
height: auto;
}
.container > p {
position: absolute;
left: 300px;
bottom: 200px;
}
<div class="container">
<img src="https://pngimg.com/uploads/surfing/surfing_PNG9721.png" class="img">
<p>Im absolute
</p>
</div>

Related

Cropping the top 10% of an image using CSS?

How to crop the top of an image has already been described in this question. However, I am trying to crop an image by a percentage when the image dimensions are not known ahead of time. The container's resulting height should then be dependent on the size of the image.
Using the following, I can crop the top of an image, but it requires manually specifying the amount of the image to show in pixels. Is there a way I can specify I want to crop the top 10% of the image without knowing the image size ahead of time?
.container {
overflow: hidden;
position: relative;
height: 370px;
}
.container img {
position: absolute;
margin-left: auto;
margin-right: auto;
bottom: 0;
left: 0;
right: 0;
}
<div class="container">
<img class="img" src="http://placekitten.com/400/500" />
</div>
Here is an idea that rely on scale. You keep the image in-flow (don't use position:absolute) then you scale the container by 0.9 which is 90% of the total height then you scale the image by 1.1 to keep it's original size. This will trim the image by 10% but since transform is only a visual effect you may have space at the top or the bottom of the container (based on the transform-origin)
.container {
overflow: hidden;
outline:1px solid red;
display:inline-block;
}
.container img {
display:block;
}
.cut {
transform:scaleY(0.9);
transform-origin:top; /* The extra space will be on the bottom*/
}
.cut img {
transform:scaleY(1.1);
transform-origin:bottom; /* This should be bottom to cut the top*/
}
<div class="container">
<img class="img" src="http://placekitten.com/300/200" >
</div>
<div class="container cut">
<img class="img" src="http://placekitten.com/300/200" >
</div>
To be more precise we can consider calc() like below:
.container {
overflow: hidden;
outline:1px solid red;
display:inline-block;
}
.container img {
display:block;
}
.cut {
transform:scaleY(0.9);
transform-origin:top; /* The extra space will be on the bottom*/
}
.cut img {
transform:scaleY(calc(1/0.9));
transform-origin:bottom; /* This should be bottom to cut the top*/
}
<div class="container">
<img class="img" src="http://placekitten.com/300/200" >
</div>
<div class="container cut">
<img class="img" src="http://placekitten.com/300/200" >
</div>
I think the best approach to this without Javascript would be to translate the image up a certain percent, then scale it to fill the original height of the container. Anything else will leave a gap at the bottom.
.img_container img {
transform: translateY(-50%) scale(2);
}
https://jsfiddle.net/amoliski/n4ojdzyr/
This should do the trick, using translateY (got that from How can I get the height of an element using css only)
As you can see, the .container does not have a hardcoded height, however, it will load with the original image height, which is 500px, even though the image is loading as 450px (500px - 10%)
.container {
overflow: hidden;
position: relative;
}
.container img {
margin-left: auto;
margin-right: auto;
bottom: 0;
left: 0;
right: 0;
transform: translateY(-10%);
}
<div class="container">
<img class="img" src="http://placekitten.com/400/500" />
</div>
You can do this with a little bit of JavaScript (I've inlined it for simplicity's sake but you could move it to it's own function)
<div class="container">
<img class="img" src="http://placekitten.com/400/500" onload="javascript:this.parentElement.style.height = (this.height * 0.9)+'px';" />
</div>
Here's a working JSfiddle.
An alternative would be to use the top CSS property in a negative fashion on a relative image like the snippet below. This works for an image of an arbitary width and height. Just adjust your top value, accordingly.
html,body{ height:100%; margin:0; padding:0; }
.container {
overflow: hidden;
position: relative;
height: 100%;
width: 100%;
display:flex;
margin-bottom: -10%;
align-items:center;
justify-content:center;
}
.container img {
position: relative;
bottom: 0;
left: 0;
height: 100%;
top: -10%;
right: 0;
}
<div class="container">
<img class="img" src="http://placekitten.com/400/500" />
</div>
To remove the extra bottom margin, just subtract the margin-bottom equal to the amount you subtracted from the top. Here it is margin-bottom: -10%;
Adjust the top value according to your dynamic images. Also note, I added height:100% to your container so you can see the full image but the top part is cropped. I used flex for centering. Test for another image but this time, it is cropped 50% from the top
html,body{ height:100%; margin:0; padding:0; }
.container {
overflow: hidden;
position: relative;
height: 100%;
width: 100%;
margin-bottom: -50%;
display:flex;
align-items:center;
justify-content:center;
}
.container img {
position: relative;
bottom: 0;
left: 0;
height: 100%;
top: -50%;
right: 0;
}
<div class="container">
<img class="img" src="https://www.fujifilm.com/products/digital_cameras/x/fujifilm_x_t3/sample_images/img/index/ff_x_t3_002.JPG" />
</div>

height: 100% of overflowed content

Is it possible to make an element with position: absolute; have the full height of its parent, including overflowed content?
In the following code snippet the .line element gets cut off when scrolling the .container:
.container {
position: relative;
height: 150px;
width: 300px;
overflow-y: scroll;
}
.line {
position: absolute;
background: #000;
width: 2px;
left: 50%;
height: 100%;
}
<div class="container">
<div class="line"></div>
<div style="height: 500px;"></div>
</div>
Adding another wrapper can solve the issue:
.container {
height: 150px;
width: 300px;
overflow-y: scroll;
}
.container > div {
position: relative;
}
.line {
position: absolute;
background: #000;
width: 2px;
left: 50%;
height: 100%;
}
<div class="container">
<div>
<div class="line"></div>
<div style="height: 500px;"></div>
</div>
</div>
The height: 100%; of the absolutely positioned element refers to the given CSS heigth (i.e. the height defined in the CSS rule) of the relative parent, not to its stretched "real height" when it overflows. So it will always have the initial parent height which is defined via CSS.
To achieve what you want, you'd have to get the parent height via javascript and apply it to the child.

Position absolute inside one relative above another relative

The question is: is it possible? I have a div with relative position. Inside this div, I have another div with position: absolute and top: whatever.
This absolute positioned div overlaps content in parent div without any problems, but another relative position div (outside parent) doesn't even care. Before this question I googled as I much as I could, so I'm for 90% sure that it's impossible, or I'm on a wrong way, but I need to be sure.
Here is an example http://jsfiddle.net/MNLbZ/2/
HTML
<div class="main">
<div class="content">11112222233</div>
<div class="abs"></div>
</div>
<div class="main"></div>
CSS
.main {
background: green;
position: relative;
height: 100px;
width: 100px;
z-index: 100;
}
.content {
position: relative;
z-index: 500;
width: 100px;
}
.abs {
position: absolute;
width: 50px;
height: 300px;
top:0;
right: 0;
background: red;
z-index: 999;
opacity: .5;
}
The z-index of the second .main div must be lower than that of the first div that contains the absolute div:
add a class to the second main
<div class="main">
<div class="content">11112222233</div>
<div class="abs"></div>
</div>
<div class="main second"></div>
then use this style:
.second {z-index:99;}
Example

How to ignore parent element's overflow:hidden in css

I have a div element wrapping other div elements like so:
<div style="overflow:hidden">
<div id="a"></div>
<div id="b"></div>
</div>
I have other css rules that manage the dimensions of the outer div. In my actual code, I want to position the div#a exactly 10 px below the outer div. However, I want div#b to still be cut off by the outer div's overflow:hidden.
What is the best way to achieve this?
Method 1
A good way to do it is by setting the overflowing element to position:fixed (which will make it ignore the parent overflow), and then positioning it relative to the parent using this technique:
​.parent {
position: relative;
.fixed-wrapper {
position: absolute;
.fixed {
position: fixed;
}
}
}
One caveat is that you cannot have any of the top,right,left,bottom properties set on the fixed element (they must all be default 'auto'). If you need to adjust the position slightly, you can do so using positive/negative margins instead.
Method 2
Another trick I recently discovered is to keep the overflow:hidden element with position:static and position the overriding element relative to a higher parent (rather than the overflow:hidden parent). Like so:
http://jsfiddle.net/kv0bLpw8/
#wrapper {
width: 400px;
height: 50px;
position: relative;
z-index: 1000;
left: 0px;
top: 0px;
}
#wrapper #insideDiv {
width: 400px;
height: 50px;
overflow: hidden;
position: absolute;
z-index: 2000;
left: 0px;
top: 0px;
}
#wrapper #a {
position: absolute;
height: 30px;
width: 100px;
bottom: -40px;
z-index: 1000;
left: 0px;
}
<div id="wrapper">
<div id="a">AAA</div>
<div id="insideDiv">
<div id="b">BBB</div>
</div>
</div>
The easiest and most convenient way is to wrap your container div inside another div and set position: relative on the external div.
.outer-container {
position: relative;
height: 50px;
}
.container {
background: gray;
overflow: hidden;
height: 50px;
}
#a,
#b {
height: 100px;
width: 100%;
}
#a {
background: green;
position: absolute;
top: 60px;
}
#b {
background: red;
font-size: 60px;
}
<div class="outer-container">
<div class="container">
<div id="a"></div>
<div id="b">Cut off</div>
</div>
</div>
as people said, the element must be presented outside the parent in order to be not cropped. But you can do this with JavaScript to achieve the similar concept without having to change your actual markup:
function breakOverflow(elm) {
var top = elm.offset().top;
var left = elm.offset().left;
elm.appendTo($('body'));
elm.css({
position: 'absolute',
left: left+'px',
top: top+'px',
bottom: 'auto',
right: 'auto',
'z-index': 10000
});
}
then pass the element you want to exclude from the cropping of its parent:
breakOverflow($('#exlude-me'));

position fixed margin divs in scrollable content

Hello
please have a look at my jsfiddle.
The content of the inner div-element is scrollable.
Each grey symbol has a margin-left. When I scroll the content the symbols shouldn't be fixed to the background.
It should be scrollable with the position.
Have you got an idea how I achieve that effect?
Keep in mind that positioning is relative to the closest positioned parent.
When you are assigning an absolute position to the "symb" class you are positioning them relative to the document rather than their parent.
Simply adding "position: relative;" to your div.tl element will set the parent div as positioned without moving it and the "symb" elements will act the way I think you expect them to.
Your new .tl definition should be:
.tl {
width: 500x;
height: 80px;
background-color:grey;
position: relative;
}
Furthermore, I'm assuming that you have some need to position these absolutely. You could achieve similar results by simply removing the "position: absolute" portion of your .symb definition.
You are setting a margin, not a position, so you don't need to bother with positioning at all in your example case.
I am not sure what do you need. You had an error in your last "symb" - you missed 'p' in 'px'. Try this?
<div class ="outer">
<div class="inner">
<div class="tl">
<div class="box" style="width: 315px;">
<div class="symb" style="margin-left: 0px;"></div>
<div class="symb" style="margin-left: 15px;"></div>
<div class="symb" style="margin-left: 20px;"></div>
</div>
</div>
</div>
</div>
.outer {
width:50%;
}
.inner {
overflow-x:scroll;
}
.tl {
width: 500x;
height: 80px;
background-color:grey;
}
.box {
float: left;
height: 61px;
}
.box .symb {
float:left;
width: 5px;
height: 5px;
background-color: #cccccc;
z-index: 999;
margin-top: 10px;
}
Use
position: relative;
Not
position: absolute;
Just try with the following CSS:
.box .symb {
position: relative;
float: left;
position: inline-block;
width: 5px;
height: 5px;
background-color: #cccccc;
z-index: 999;
margin-top: 10px;
}

Resources