Hidden text element within centered absolute div - html

I'm having trouble getting a h2 header to appaer within an absolutely positioned element. I've ran through the list of possible errors, but still can't seem to find the answer. The h2 element, after inspecting the screen, has a height of 0 for some reason.
Here's a codepen link
HTML:
<div class="gallery">
<img class='gallery-image' src='https://dummyimage.com/200x400/000000/ffffff'>
<img class='gallery-image' src='https://dummyimage.com/200x400/000000/ffffff'>
<img class='gallery-image' src='https://dummyimage.com/200x400/000000/ffffff'>
<img class='gallery-image' src='https://dummyimage.com/200x400/000000/ffffff'>
<a class='call-action' href='#'>
<h2>Shop Now.</h2>
</a>
</div>
CSS:
.gallery {
position: absolute;
z-index: 2;
width: 100%;
display: flex;
flex-wrap: wrap;
font-size: 0;
img {
display: block;
width: 25%;
height: 50%;
#media only screen and (max-width: 500px) {
width: 50%;
height: 100%;
}
}
}
$call-action-width: 150px;
$call-action-height: 50px;
.call-action {
width: $call-action-width;
height: $call-action-height;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 0;
background-color: white;
opacity: 0.5;
border-radius: 5%;
h2 {
position: relative;
color: black;
font-size: 2em;
}
}
Sorry if the answer is obvious - I've just returned to practicing coding and I'm extremely rough.
Thanks for your help!

The problem lies in your font-size. You can't have an em font within a position: absolute <div>, as em is relative to the parent element.
Simply swapping to a fixed-size font (such as px) fixes the problem. I've created a new pen showcasing this here.
Unfortunately this means that your font can't be responsive. If you want responsive font, you'll either have to use a few media queries, or restructure your HTML so that the <h2> element has a position: relative parent (so you can use em).
Hope this helps! :)

Related

Width percentage value not being applied to element

I am styling an element in HTML using Sass, and when setting the width of an element using percentages, it is not applied.
Could this be due to me setting the parent element's width and height using "content-max"?
Here is a basic version of the code I am using, the idea is for the parent's size to be limited by the image size (which works), and for the text overlay to be half the width and the full height of the container element (hence me using 50 and 100 percent respectively).
<div class="container">
<img src="image.png" alt="A square image">
<div class="text-overlay">
</div>
</div>
The separately complied Sass is as follows:
.container {
display: block;
position: relative;
width: max-content;
height: max-content;
img {
display: block;
position: absolute;
z-index: 0;
}
.text-overlay {
display: flex;
position: absolute;
width: 50%;
height: 100%;
z-index: 1;
}
}
Both HTML and SCSS are written in different files and correctly complied where necesary.
As mentioned in the comments, you can not write Sass directly inside your HTML markup. It has to be compiled first.
In your example you are using nesting, which is not valid CSS3 code, so to fix this behavior you either have to write plain CSS like the snippet below or compile your Sass before you apply it to your HTML.
About your actual question, the positioning you are trying to archieve is working, when you hardcore the width and height to the .container element.
.container {
position: relative;
width: 200px;
height: 200px;
}
.container img {
position: absolute;
z-index: 0;
}
.container .text-overlay {
position: absolute;
z-index: 1;
width: 50%;
height: 100%;
background-color: green;
color: red;
opacity: 50%;
}
<div class="container">
<img src="https://i.picsum.photos/id/793/200/200.jpg?hmac=3DeE830wjdSShKq_h_iFtV_jAxf43FO4xx-sivW0Q_Y">
<div class="text-overlay">
Overlay
</div>
</div>

contain image in 60%-height-div, while keeping aspect ratio

What I am trying to accomplish:
- create a pop-up div (fixed), centered in view
- this pop-up should be 60% height of the browser window
- the contents of the pop-up should be an image and a 'x' above the upper right corner of the image
- the height of the image should be maximal, considering it should be contained in the div together with the 'x'
- the aspect ratio of the image should be maintained
I tried the following code
<div class="pop-up">
<p class="exit-button">x</p>
<img class="image" src="safari.png" width="1200" height="630" alt="" title="" />
</div>
With CSS:
body {
background: #333;
}
.pop-up {
position: fixed;
height: 60%;
width: auto;
left:50%;
top:50%;
-webkit-transform:translate(-50%,-50%);
transform:translate(-50%,-50%);
background:yellow;
object-fit: contain;
}
.exit-button {
text-align: right;
margin: 0;
font-size: 300%;
}
.image {
height: 100%;
width: auto;
opacity:0.7;
}
This code is not solving the problem, the image is not contained in the (yellow) div, as can be seen in the following screen shot:
http://www.michielvisser.nl/tmp/screenshot.jpg
How to contain the image in the div with maximal height for the image in the div and maintain aspect ratio?
SOLUTION 1: Remove the height and width from .pop-up and change height:100% in .image to height:60vh. That works perfectly. Apparently the child (img) will not adjust to the parent (div), but the parent (div) will adjust to the child (img). Sounds like real life.
SOLUTION 2: Essentially the problem arises when the window is resized (except in firefox). The solution can be to redraw the image after a resize, this solves the problem:
$(window).resize(function(){
$('img').hide();
setTimeout(function(){ $('img').show(); }, 1);
});
Your problems are:
You have an inline width and height set on your image, which is overriding the CSS styles for width and height on that image
The margin from your X is pushing the image down since the X is wrapped in a <p> tag.
You don't need object-fit at all.
The simple way to solve #1 is to delete the inline width and height from the image tag and leave it to the stylesheet.
Number 2 can be solved by wrapping the X in a div instead of a p, or you can use a pseudo element for it. I have taken the latter approach in the snippet below.
To solve #3, just delete the style from the stylesheet. (Having this property set in Safari actually messed things up for me.)
This snippet is tested in Safari 10.1.1. Note how the placeholder image is quite large by default (1000x800), but it only displays as big as it can per the parent div.
Edit: Based on your comments, let's revise this further so that we dictate the size on the image, and just let the wrapper take up the size of the image.
So on our image, in order to get it to be 60% as tall as the screen, we can do:
img {
height: 60vh;
width: auto;
}
Then, in our parent, we won't specify a width or height at all, but we can do display: flex just to make sure it is big enough to fit its contents.
body {
background: #333;
}
.pop-up {
display: flex;
position: fixed;
left: 50%;
top: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
background: yellow;
}
.exit {
color: black;
text-decoration: none;
text-align: center;
font-size: 300%;
display: block;
position: absolute;
top: -50px;
right: -40px;
width: 40px;
height: 50px;
}
.image {
height: 60vh;
width: auto;
opacity: 0.7;
}
<div class="pop-up">
X
<img class="image" src="http://placehold.it/1000x800" alt="" title="">
</div>
I put the image above the P tag and added some CSS to .exit-button and .image
From here you can adjust padding and sizing of the elements.
body {
background: #333;
}
.pop-up {
position: fixed;
height: 60%;
width: auto;
left:50%;
top:50%;
-webkit-transform:translate(-50%,-50%);
transform:translate(-50%,-50%);
background:yellow;
object-fit: contain;
}
.exit-button {
position: absolute;
text-align: right;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: 0;
font-size: 300%;
}
.image {
height: 100%;
width: auto;
opacity:0.7;
}
<div class="pop-up">
<img class="image" src="http://icons.iconarchive.com/icons/johanchalibert/mac-osx-yosemite/1024/safari-icon.png" width="1200" height="630" alt="" title="" />
<p class="exit-button">x</p>
</div>
I copied your code and edited it. Please tell me whether this is the output you wanted or not.
body {
background: #333;
}
.pop-up {
position: fixed;
height: 60%;
width: auto;
left:50%;
top:50%;
padding-top: 30px;
-webkit-transform:translate(-50%,-50%);
transform:translate(-50%,-50%);
background:yellow;
object-fit: contain;
}
.exit-button {
margin-top: -50px;
text-align: right;
margin-right: 0;
font-size: 300%;
}
.image {
margin-top: -20px;
height: 100%;
width: auto;
opacity:0.7;
}
<div class="pop-up">
<p class="exit-button">x</p>
<img class="image" src="safari.png" alt="" title="" />
</div>
Because of either needing to hardcode in the alignment of the image given the size or deal with weird convolution, I believe this is the best way:
Create a fixed overlay occupying the entirety of the screen, create a container of 60% height, align it in the center with flexbox and stick the image inside making it occupy the entire height. The aspect ratio will update automatically (only happens with height).
As for the button – give it absolute positioning and a right position of 0, and manually give the parent relative positioning (this is necessary).
<div id="popup">
<div id="container">
X
<img src="https://i.redd.it/gelilvo30mgz.jpg">
</div>
</div>
html,
body {
height: 100%;
}
#popup {
position: fixed;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
#container {
position: relative; !important // has to be specified for the children (anchor) to find the bound
height: 60%;
background: #333;
}
a {
right: 0;
position: absolute;
}
img {
height: 100%;
}
https://jsfiddle.net/L2nLjjxc/1/
I believe that's the least amount of convolution if you want it to be dynamic.

Child div height determines parent height?

I have a parent div that contains two children, side by side. The first child is an image that must be height 100% and 58% width, margin auto and overflow hidden. The second child contains text, and the length of the text determines the height of the parent. This is a template for several pages, with different length of text, and therefore different parent height. Is it possible to do what I'm trying to do without using JS? Thanks for your input! Code below.
HTML:
<div id="product-summary">
<div class="product-image-container">
<img />
</div>
<div id="product-details">
<h3 class="product-title"></h3>
<div class="product-description"></div>
</div>
</div>
CSS:
.product-image-container {
position: absolute;
top: 0;
left: 0;
width: 58%;
height: 100%;
overflow: hidden;
img {
position: absolute;
top: 0;
left: 50%;
margin: auto;
transform: translateX(-50%);
min-width: 100%;
height: 100%;
}
}
#product-details {
float: right;
border: solid thin #777;
height: ~"calc(100% - 2px)";
width: 41%;
text-align: center;
}
The problem is your #product-details is floated, which creates a new BFM (block formatting context), and the parent gets collapsed.
I suggest you read more about BFMs here: http://yuiblog.com/blog/2010/05/19/css-101-block-formatting-contexts/
There are several ways to fix this:
You could clear the parent, a way to do that is by adding overflow: hidden; to the #product-summary element.
You could remove the float: right from #product-details, and use flexbox to align it instead.
I don't know any preprocessor wizardry, but using inline-block works good, as well as keeping positioned absolute elements wrapped in a relative parent for control. It wasn't mentioned how the image is displayed, so I assume aspect ratio unchanged and no cropping.
SNIPPET
.product-image-container {
display: inline-block;
position: relative;
top: 0;
left: 0;
right: 0;
width: 58%;
height: 100vh;
overflow: hidden;
}
img {
display: inline-block;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: auto;
}
#product-details {
float: right;
border: 1px solid #777;
height: 100%;
width: 41%;
text-align: center;
}
a {
margin-left: 50%;
}
<div id="product-summary">
<div class="product-image-container">
<img src='https://upload.wikimedia.org/wikipedia/en/2/24/Lenna.png'>
</div>
<div id="product-details">
<h3 class="product-title">Lena Söderberg</h3>
<div class="product-description">
<blockquote>Lenna or Lena is the name given to a standard test image widely used in the field of image processing since 1973. It is a picture of Lena Söderberg, shot by photographer Dwight Hooker, cropped from the centerfold of the November 1972 issue of Playboy
magazine.
</blockquote>
<a href='https://en.wikipedia.org/wiki/Lenna'>Wikipedia</a>
</div>
</div>
</div>

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

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%;
}