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%;
}
Related
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
I'm trying to get a child DIV to have its padding set relative to its fixed parent DIV.
To demonstrate the problem, I've put together a quick JSFiddle - http://jsfiddle.net/mdxsegLt/
.top-fixed {
position: fixed;
top: 0px;
height: 70px;
max-height: 12.5%;
margin-bottom: 20px;
width: 100%;
left: auto;
right: auto;
z-index: 1030;
background-color: green;
}
.padding-percentage {
position: relative;
width: 50px;
max-width: 30%;
/*padding: 14px;*/
padding-top: 20%;
background-color: red;
}
<div class="top-fixed">
<div class="padding-percentage">test</div>
</div>
In that example, I'd like the red DIV to be contained entirely within the green, using 20% of the green DIVs height for the padding, not the entire page.
First things first... lets drop the ALL CAPS element names. It's bad practice these days. I think you were overdoing it a bit with your CSS declarations and by NOT nesting the text properly by wrapping it in a span or p tag. You shouldn't just have floating text that's not wrapped in a p or span tag. Wrapping it in such tags allows you to further customize like I did in my fiddle.
UPDATE
I think I actually get what you're trying to do.
CSS:
.top-fixed {
position: fixed;
top: 0px;
height: 70px;
width: 100%;
background-color: green;
}
.padding-percentage {
height: 100%;
width: 50px;
background-color: red;
}
.padding {
margin-top: 0px;
padding-top: 20px;
}
HTML:
<div class="top-fixed">
<div class="padding-percentage">
<p class="padding">TEST</p>
</div>
</div>
LINK TO FIDDLE
Looks like you needed to adjust the CSS and add a class to the "test" text by tossing it an a p tag.
Check out my fiddle and hope it helps you!
Examining this HTML:
<div class="wrapper">
<div class="content">
</div>
</div>
<div class="footer">
<hr />
<p>some text</p>
</div>
and CSS:
.footer {
position: absolute;
height: 100px;
width: 100%;
bottom: 0;
background-color: black;
}
.wrapper {
padding-bottom: 100px;
background-color: blue;
height: 100%;
}
.content {
width: 200px;
height: 100px;
margin: auto;
background-color: green;
}
html, body {
width: 100%;
height: 100%;
}
You can see that footer have position absolute and stay at the bottom of the page. wrapper will cover the remaining space and contain a content inside it. I want to vertical-align content without breaking the current layout. Do you have any suggestion?
Here is JSFiddle link. (Note: jsfiddle doesn't work as expected, there always a space beneath footer, this behavior doesn't occur when run the HTML file in browser).
Note: I don't want to use fixed height for wrapper, I want it covers all the remaining space, so please don't suggest me to use line-height
I tried the example here but it doesn't seem to work
NOTE I want the layout easy to modify (like add a header or content at the top) without breaking it therefore I want to avoid using absolute position on wrapper and content
NOTE 2 Sorry for not to clarify, actually, content doesn't have fixed size, its size depend on the content inside it, so the solution using negative margin doesn't work as I mentioned above
Here is one approach using the following CSS:
.footer {
position: absolute;
height: 100px;
width: 100%;
bottom: 0;
background-color: black;
}
.wrapper {
background-color: blue;
position: absolute;
top: 0;
bottom: 100px;
left: 0;
right: 0;
}
.content {
width: 200px;
height: 100px;
background-color: green;
position: absolute;
top: 50%;
left: 50%;
margin-top: -50px;
margin-left: -100px;
}
html, body {
width: 100%;
height: 100%;
margin: 0;
}
Use absolute positioning and then negative margins, since your content has well-defined
dimensions, this is relatively straightforward.
See demo at: http://jsfiddle.net/audetwebdesign/DgUV2/
For .wrapper, use the top, bottom, left and right offsets to stretch the div to the
full width and height, taking into account the 100px for the footer.
For .content, set top and left to 50%, the center point of the .wrapper and then adjust
for the center of the .content div using negative margins.
Remember to zero out the margin for the body or else you might see 10px whitespace
depending on your browser.
Add this to your .content
position: relative;
top: 50%;
transform: translateY(-50%);
Just 3 lines of code to vertical align
I was able to get it to work using Method 1 from the example you linked
I added the following:
.content {
width: 200px;
height: 100px;
margin: auto;
background-color: green;
/* THE BELOW WAS ADDED */
position: absolute;
top: 50%;
left: 50%;
margin: -100px 0 0 -100px;
}
html, body {
width: 100%;
height: 100%;
/* BELOW ADDED TO REMOVE EXTRA SPACE AROUND EDGES */
margin: 0;
}
jsFiddle of working example
Click here for visual
As you can see from the picture, my parent container is not expanding to fit my child container. The page container (#contain) actually stops at the bottom left hand corner of the kitchen photograph. The child container (#zone2) is clearly overflowing outside its parent container (#contain). I would like to be able to have (#contain) expand automatically to fit (#zone2). The CSS is:
#contain {
position: relative;
width: 100%;
margin: 0 px;
background: #E3DCCC;
z-index: 0;
}
#zone1 {
width: 100%;
height: 850px;
background: url(http://waly1039.com/sites/default/files/k4.jpg) no-repeat center top;
position: absolute;
z-index: -1;
}
#head {
position: absolute;
top: 20px;
width: 100%;
height: 330px;
}
#head img {
max-width: auto;
height: auto;
}
#zone2 {
position: relative;
overflow: hidden;
padding: 3px;
top: 360px;
float: right;
right: 15px;
width: 53%;
height: auto;
border: 4px solid #715E40;
background-color: white;
}
#zone2 img {
max-width:100%;
height: auto;
float:left;
margin: 5px;
}
#zone3 {
position: relative;
top: 710px;
left: 15px;
float: left;
height: 340px;
width: 38%;
border: 4px solid #715E40;
background-color: white;
}
This is a float issue. Try adding the traditional CSS clear fix to #zone2's container:
.container:after{
visibility: hidden;
display: block;
font-size: 0;
content: " ";
clear: both;
height: 0;
}
Be sure to put this in the :after pseudo selector, otherwise it won't work for you. Floated elements exist outside of normal document flow, which is why the container isn't expanding to contain them. The clear fix forces the floats to be cleared, which will cause the container to expand around the bottom of this element.
I tested adding more images to #zone2 and #contain expands vertically. Somehow you've got an element(s) in #zone2 with padding or margins that aren't being added to the parent's total height.
If you want a quick fix in order to move on then add margin-bottom: 30px; to #zone2.
I've duplicated your problem and was able to resolve it with this: You might want to try it. It's looks a bit odd so make a class for it if you like. I'm more concern with where it is placed.
Just beneath lines of your code, add my third line. Just that and you are done. Note, it more about positioning.
<div id="zone3"></div>
<div id="zoneclear"></div>
<br style="clear:both; float:none; display:block; height:1px;" />
Just add the third line.
and just modify one of your styles:
#zoneclear {
clear: both;
float:none;
display:block;
height: 30px;
position: relative;
}
[EDIT]
The codes have a serious bug in firefox which is not present in Google Chrome (that I tested in earlier due to your relative positioning. So I've modified the #zoneclear style to fix that. You might have to test if the other browsers like this hack.
I hope it helps you
SO,
I've created a four-column fluid-width layout for a site, and I'm working on placing a fluid square DIV within one of my columns. There are a few techniques I've found to achieve this - namely, setting padding-bottom to the same percentage as the width - but none of these seem to work when the DIV contains content.
Is there a way to maintain a 1:1 (square) ratio on a fluid DIV when that DIV contains content?
Here's my HTML:
<div id="leftmostcolumn">
<div id="logo"></div>
</div>
<div id="leftcolumn"></div>
<div id="rightcolumn"></div>
<div id="rightmostcolumn"></div>
And my CSS:
body {
width: 100%;
height: 100%;
background-color: red;
}
#leftmostcolumn {
position: absolute;
top: 0;
left: 0;
width: 25%;
height: 100%;
background-color: blue;
}
#leftcolumn {
position: absolute;
top: 0;
left: 25%;
width: 25%;
height: 100%;
background-color: green;
}
#rightcolumn {
position: absolute;
top: 0;
left: 50%;
width: 25%;
height: 100%;
background-color: yellow;
}
#rightmostcolumn {
position: absolute;
top: 0;
left: 75%;
width: 25%;
height: 100%;
background-color: gray;
}
#logo {
width:100%;
padding-bottom:100%;
background-color: #aa2d2d;
color: white;
}
And here's a JsFiddle.
The DIV "logo" is the one I'm trying to maintain as a square. Right now, I've used the padding-bottom approach but that doesn't do the trick when there's content in the DIV. Any input is greatly appreciated!
Marca
EDIT:
Getting there...I'm adapting a script I found to find the width of the DIV and then apply that value to the height to keep it a square. However, as it stands now the script doesn't constantly resize the DIV, and it won't allow it to shrink below a certain size. Any thoughts on how to correct either of these issues?
HTML:
<div id="box"></div>
CSS:
#box { width: 75%; height: 50px; background-color: black; }
JQUERY:
$("#box").css("height", function() {
return $(this).width();
});
JsFiddle is here.
This is something I've actually been messing around with for a while, and have come up with a quasi (but not entirely) hacky, CSS-only solution that seems to work on most browsers in the past decade. The trick is to use images, and positioning in a tricky fashion. Consider the following (simplification) of your code.
Markup:
<div class="sqr_box">
your content goes here!
</div>
CSS:
.sqr_box
{
width: 50%; /* or 100px, or 20em, or whatever you want */
border: solid 2px pink;
background-color: grey;
color: white;
}
Now, we can't set the height in terms of percent, so we won't; instead, first we'll go into Photoshop, and make an image that is 2x2 px, transparent, or background-colored. Next we'll add the following to your markup:
<div class="sqr_box">
<img src="images/sizers/2x2.png" class="sizer">
<div class="content">your content goes here!</div>
</div>
and THIS to your CSS:
.sqr_box
{
width: 50%; /* or 100px, or 20em, or whatever you want */
position: relative; /* static positioning is less than ideal for this scenario */
}
.sqr_box > img.sizer
{
display: block; /* images default to an inline-block like thing */
width: 100%;
height: auto; /* CLUTCH!!! this ensures that the image's height changes to maintain proportions with it's width */
visibility: hidden;
}
.sqr_box > .content
{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%; /* Our parent element now has a dynamically assigned height, this will work */
border: solid 2px pink;
background-color: grey;
color: white;
}
Best of all, this will work for any sized ratio of box you'd want! Just change the proportions of the image!
Hope this is all still relevant to you, 3 months later.
-Sandy
Put all four columns in one div. set that div to 100% width and set the font size to 100em
Have each of your four columns have a width of 25em instead of 25%
Have your logo width and height set to 25em each