Absolute positioning breaks the structure completely - html

Here's the basic HTML code:
<div class="soc-cont">
<div class="soc-item-cont" style="background: blue;">
<div class="soc-item">
<img src="img/facebook.png" style="width: 100%; position: absolute; left: 0;">
</div>
</div>
</div>
And here's the CSS:
.soc-cont {
position: absolute;
height: 100%;
width: 20%;
display: inline-block;
right: 0;
text-align: center;
font-size: 0;
}
.soc-item-cont {
width: 25%;
height: 100%;
position: relative;
display: inline-block;
}
.soc-item-cont:before {
content: "";
display: inline-block;
vertical-align: middle;
height: 100%;
}
.soc-item {
vertical-align: middle;
width: 50%;
display: inline-block;
position: relative;
background: black;
}
What I'm trying to do is add position: absolute and left: 0 to to the img in order to take it out of the usual document flow to be able to overlap it with another picture later on. But instead of working as it should, I get this:
Instead of this:
Note: I have color-coded it a little to be more easily understood.
It also should be noted that there are, in fact, four .soc-items. However, since they are, right now, nothing more than copies to fill up the space, I didn't deem it necessary to post it here, as it would probably confuse you even more.
However, all it takes is changing position to absolute to instantly break the look.
Any ideas on how to fix this?

The reason for your problem is that, by changing it to position:absolute, you are taking it out of the normal flow but that causes your div(s) to collapse cause they now have no content (essentially). Once they do, you have to deal with the image being on the baseline and having white space, just like text. So it's the same as if you inserted or removed that content. Your layout "adjusts" to the content.

Related

Using CSS "padding-trick" for proportional resizing on Y-axis?

I'm building an web app which has a 100% height/width/fullscreen layout. I am looking for a CSS-trick to proportionally resize an elements dimensions according to its height.
Right now I am looking for an equivalent of what this trick does to the x-axis:
html, body{
height:100%;
margin:0;
}
#view {
min-height: 100%;
position: relative;
width: 100%;
background-color: #333333;
}
#test-hld {
position: absolute;
display: flex;
align-items: center;
justify-content: center;
background-color: tomato;
width: 100%;
height: 75%;
}
.test{
position: relative;
width: 30%;
}
.test:before{
content: "";
display: block;
padding-top: 75%;
}
.content{
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
background: black;
}
<div id="view">
<div id="test-hld">
<div class="test">
<div class="content"></div>
</div>
</div>
</div>
But changing (for example) .test{height: 80%} and .test:before{padding-left: 75%} makes the browser render no dimensions of the box at all.
My question(s) is
Why is the opposite not working?
Has it something fundamental to do with setting heights of elements with CSS?
Can flex/flexbox solve this?
I know it's possible to fix this with some lines of JS but I just can't believe it's not doable with CSS until someone slaps my face telling me to get real.
First of all, just to know why the padding trick works.
Padding-top and padding-bottom are vertical dimensions that are related to the width (so, an horizontal dimension) of the container.
That allows the ratio of an element to be fixed, and related to the width of the container. But there isn't any horizontal dimension that is related to some vertical of the container, so the equivalent trick over the height is not posible right now.
I have tried to get this same result using another technique, but I have had a very partial success.
My failed attempt is try to use an image to set the ratio
body, html {
height: 99%;
}
.base {
height: 40%;
border: solid 1px green;
display: inline-block;
position: relative;
}
.ratio {
content: url("http://placehold.it/400x200");
opacity: 0.05;
height: 100%;
width: auto;
position: relative;
}
<div class="base">
<img class="ratio" />
</div>
This is working in IE and Chrome, and failing in FF. But just on initial loading.
Changing the browser size won't work until the page is reloaded. I just can't figure out why, or how to solve it

Setting an inline element's percentage css height, relative to it's flexible parent. (Only problems with chrome)

Problem:
I'm trying to make a scalable view for images in a lightbox. I've got a way to make it look good on every size of screen. But, only Google Chrome's behavior to this method is different from the other browsers.
HTML:
<div class="parent">
<span class="helper"></span>
<img src="">
</div>
CSS:
I create a helper element, setting it's display to inline-block and change the vertical-align to middle for both span and img. This makes sure the image will be placed in the middle of it's parent.
To make sure the height and width of the image won't be any bigger than it's parent, I set it both to 90%. (not 100% 'cause I want some padding as well).
So my CSS looks like this:
.parent{
position: absolute;
top: 0;
right: 0;
bottom: 100px;
left: 0;
background-color: #ccc;
text-align: center;
}
.helper{
display: inline-block;
vertical-align: middle;
height: 100%;
}
img{
vertical-align: middle;
max-width: 90%;
max-height: 90%;
}
Fiddle
In this fiddle you can see that it work's in all browsers except for Google Chrome. Chrome ignores the maximum height that's set. Which will allow the image to be bigger than it's parent, not good..
Is there a work-around for this problem?
check this out with pure css , no js/jquery. just you need to wrap your content in div and give height 100% to it, as when you say max-height: 80% it takes 80% of it's parent which was not there.
.parent{
position: absolute;
top: 0;
right: 0;
bottom: 100px;
left: 0;
background-color: #ccc;
text-align: center;
}
.helper{
display: inline-block;
vertical-align: middle;
height: 100%;
}
img{
vertical-align: middle;
max-width: 90%;
max-height: 80%;
}
<div id = "parentDiv" class="parent">
<div style="height: 100%;">
<span class="helper"></span>
<img id = "imgId" src="http://3d-diva.davidmichaeldesigns.com/images/tree-01.png"/>
</div>
</div>
Hope this is what you are looking for :)
you can pass height to image tag dynamically with respect to parents div through javascript.
function setImgHt(){
var imgHeight = document.getElementById('parentDiv').clientHeight;
document.getElementById('imgId').setAttribute("style","height:"+imgHeight+"px");
}
.parent{
position: absolute;
top: 0;
right: 0;
bottom: 100px;
left: 0;
background-color: #ccc;
text-align: center;
}
.helper{
display: inline-block;
vertical-align: middle;
height: 100%;
}
img{
vertical-align: middle;
max-width: 90%;
max-height: 80%;
}
<body onload="setImgHt()">
<div id = "parentDiv" class="parent">
<span class="helper"></span>
<img id = "imgId" src="http://3d-diva.davidmichaeldesigns.com/images/tree-01.png"/>
</div>
</body>
it can be done through jquery as well on document ready call the function which is being called onLoad now.

getting auto-width to work with absolute position from left

I'm trying to apply absolute position on an error label elemennt, which is inside an input field that is also positioned absolutely. The problem is that auto-width on the error element won't apply correctly, and will break after the first word. Why is that happening? If I use position right instead of left, it seems to work fine. Here's a jsfiddle link: http://jsfiddle.net/u793ata5/
Here's the HTML code:
<div id="outside">
<div id="inside">
<label class="error">Show this error on the side</label>
</div>
</div>
And CSS:
#outside {
position: relative;
width: 250px;
height: 250px;
}
#inside {
position: absolute;
top: 30%;
height: 30px;
left: 40%;
width: 80%;
}
.error {
width: auto;
position: absolute;
left: 90%;
top: 10%;
background-color: red;
color: white;
}
Why so many absolutely positioned elements? Maybe I'm not understanding what you want the layout to look like--and maybe you could clarify--but this modified fiddle looks more reasonable to me.
http://jsfiddle.net/u793ata5/3/
.error {
background-color: red;
display: block;
margin-left: 50%;
color: white;
}
I try not to use position: absolute unless I...uh absolutely have to.
You're putting it's position at 90% from the left. This means it only has 10% of the parent width to place text before wrapping. Try using
float: right;
instead of
left: 90%;

Inline-block conainting image with height 100% collapsing in FireFox

I have a problem with CSS that's only visible in FireFox (cur.ver. 31).
I am trying to make a responsive layout, with a row of images (with links), that are centered, and having the same height and scale with the viewport width. My approach is to create a container with a fixed aspect ratio, and place the images inside (each image inside a separate <a> tag), center them, and scale their heights to the container height. It's working great, except in FireFox.
To achieve this I applied a display: inline-block; height: 100% to <a> tag and height: 100%; width: auto to <img> tags. For some (unknown) reason FF is not calculating the width of the <a> tag correctly (when it contains described above <img> tag) and it collapses horizontally. The result is, that all <a> with 0 width are placed very close to each other (separated only by white spaces), and the images overlap each other. I get the same result with display: block; float: left; on <a> tags.
The CSS
.container-ratio {
width: 100%;
height: 0;
position: relative;
padding-bottom: 10%;
background: #ddd;
}
.container-inner {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: #ddf;
text-align: center;
}
.block {
display: inline-block;
height: 100%;
background: #f00;
}
.block img {
height: 100%;
width: auto;
display: block;
}
The HTML
<div class="container-ratio">
<div class="container-inner">
<a class="block">
<img src="http://placehold.it/100x80/42bdc2/FFFFFF&text=No1">
</a>
<a class="block">
<img src="http://placehold.it/150x80/242bdc/FFFFFF&text=No2">
</a>
<a class="block">
<img src="http://placehold.it/200x80/c242bd/FFFFFF&text=No3">
</a>
</div>
</div>
I think this is what your trying to do. Demo
You had no width on .block and auto on .block img.
It needs to be percentages.
.container-ratio {
width: 100%;
height: 0;
position: relative;
padding-bottom: 10%;
background: #ddd;
}
.container-inner {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: #ddf;
text-align: center;
}
.block {
display: inline-block;
width:20%;
height: 100%;
background: #f00;
}
.block img {
height: 100%;
width:100%;
display: block;
}
It's been nearly two years since this question was asked, and Firefox still exhibits this behavior.
So, for anyone in the same situation, here's a solution (only tested on Chrome 49.0 and Firefox 45.0.1).
Edit:
Originally, I used inline wrapper divs and two instances of the images, one of which was not displayed and only served as a dummy. It appears this is not necessary, as can be seen here.
All in all, it seems you can't use inline-block that way in Firefox, but all you need to do to get what you want is leave the anchors and images as inline elements. As long as the anchor's parent is a block-level element other than inline-block, and its height is specified, then you'll get the intended result.
If, for some reason, inline-block is really needed, I don't see how to work around this problem.
Note:
Beware of the "font-size: 0;" on the .block class, used to remove spaces between the images. Without this, images are seperated by whitespaces that behave like links. If the images need some space between them, adding some right or left margin as in the fiddle would be a solution.
Also, though the .block class name is no longer appropriate, I left it to stay consistent with the OP.
The modified CSS
.container-ratio {
width: 100%;
height: 0;
position: relative;
padding-bottom: 10%;
background: #ddd;
}
.container-inner {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: #ddf;
text-align: center;
}
.block {
font-size: 0;
}
.block img {
height: 100%;
margin-right: 1%;
}

Absolute Position div not pushing other content down

Most of my code in a jsFiddle:
http://jsfiddle.net/MilkyTech/suxWt/
The content should load on the first page in a white box, with overflowing content pushing the following sections of the page down. However, as can be seen the lower sections load over the top of the first page white box. I have tried changing the positioning/clears of the various sections but cannot seem to create the necessary movement.
<section class="page1">
<div class="huge-title centered">
<div id='detailsbox'>
<h1 id='eorvtitle'></h1>
<img id='eorvimage' src=''>
<div><p>lots of text lots of text
</div>
</div>
</section>
<section class="page2" id='page2'>
</section>
.page1 {
background: url('../img/bg.jpg')#131313;
background-size: cover;
height: 100%;
position: relative;
}
.huge-title {
position: absolute;
top: -20%;
right: 0;
bottom: 0;
left: 0;
margin: auto;
width: 100%;
height: 180px;
}
#detailsbox {
top: -4em;
width: 75%;
left: 12.5%;
right: 12.5%;
border: 20px solid white;
border-radius: 10px;
background-color: white;
text-align:center;
position: absolute;
float: left;
clear: both;
}
Absolute Positioning does not push containers down. It places itself above or below them based on the z-indexing. You need to enclose your absolute contents inside a relative container to push other containers downwards similar to those in jquery sliders.
you need to change .huge-title and #detailsbox to position:relative;
you can probably get rid of background-size: cover;
also change .huge-title and #detailsbox to the following:
.page1 {
background: url('../img/bg.jpg')#131313;
height: 100%;
position: relative;
}
.huge-title {
position: relative;
top: 20%;
right: 0;
left: 0;
margin: auto;
height: 100%;
}
#detailsbox {
top: -4em;
width: 75%;
left: 12.5%;
right: 12.5%;
border: 20px solid white;
border-radius: 10px;
background-color: white;
text-align: center;
position: relative;
float: left;
clear: both;
}
The proper function of an absolute position is to overlap content. If you want other content to automatically push down then use relative position.
The solution is to create an empty spacer div with float right or left. This would ensure there is space between the two.
Refer this answer
Absolute positioned elements are removed from the main flow of the HTML. That's why it's not pushing the elements below it down. It's now sitting on top of the elements before and after it rather than in between them.
You may want to check this out.
Whether or not absolute positioning makes sense in your case is hard to say without seeing the design you are trying to implement. Using default (aka "static") or perhaps relative positioning will push the other content down below the white box, but without a deign to look at it's hard to tell if that's the real solution.
You can add another empty section between page1 and page2 and give the css below
height: 100%;
Adding an empty div the size of the absolute entity between the absolute entity and other components may help.