Dynamically sizing absolutely positioned text - html

https://codepen.io/afrodiameter/pen/OwQmyd
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
#head {
position: relative;
width: 100%;
max-height: 160px;
min-width: 320px;
}
img {
width: 100%;
max-height: 160px;
}
h1 {
position: absolute;
bottom: -24px;
font-size: 6em;
}
<header id="head">
<img src="http://via.placeholder.com/1280x160" alt="header image"/>
<h1> Magro Perimeter</h1>
</header>
In the above Pen I have a div that contains both an <img> and an <h1>. I want the bottom of the <h1> to be "locked" to the bottom of the <img>.
When the user resizes the browser I want the font-size to scale accordingly while the bottom of the <h1> stays "locked" to the bottom of the <img>.
I thought using vw would be the way to go but when resizing the browser the <h1> moves vertically and thus does not stay locked to the bottom of the image.
I'd like to accomplish this without JS/jQuery or mixins. Is this possible?

are you testing with bottom:0?
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
#head {
position: relative;
width: 100%;
max-height: 160px;
min-width: 320px;
}
img {
width: 100%;
max-height: 160px;
}
h1 {
position: absolute;
bottom: 0;
font-size: 6em;
}
<header id="head">
<img src="http://via.placeholder.com/1280x160" alt="header image"/>
<h1> Magro Perimeter</h1>
</header>

A very helpful user on Reddit solved this.
h1 {
position: absolute;
top: 52%;
font-size: 6vw;
}
Why this works I'm not quite sure. It seems counterintuitive to use top as opposed to bottom.

Related

How to use img tag as background of banner with interactable content?

I want to use an img on my page as background-image of an image-slide banner. The reason is to include alt-text for accessibility reasons. To move the img in the background, I have to give it a negative z-index. Otherwise, it always shows on top of the content.
Tag-Lines are included on the banner as h1 titles. These titles can't be selected or interacted with, once the banner is in the negative z-index. So far, there is no problem. However, some of the background-images I want to include on some pages, were not taken by myself, so they need an image credit. The link which leads to the original-photo on the image-credit can't be clicked on. Optically, it's shown above the image and the banner, but it can't be clicked on.
So is there a way to make the content of the banner interactable. I could include the image as background-image, but in this case, how can I include alt-text to the background-image?
.slider {
width: 100%;
position: relative;
height: 600px;
z-index: -1;
}
.banner {
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.banner-image {
position: fixed;
top: 0;
left: 0;
object-fit: cover;
width: 100%;
height: 640px;
z-index: -2;
}
.image-credits {
background-color: black;
color: white;
padding: 2px 8px;
margin: 10px;
position: absolute;
bottom: 0;
right: 0;
}
.image-credits a {
color: white;
}
<div class="slider">
<div class="banner">
<img class="banner-image" src="https://via.placeholder.com/1280" alt="Description, what you see">
<div class="content">
<h1>Some tagline</h1>
<p class="image-credits">Photo by <a href="image-source" target="blank">Photographer</a\></p>
</div>
</div>
</div>
I tried setting the page up with positive z-values. But then the background-image always shows on top of the rest of the content on the page, and the content remains interactable. Also, I applied pointer-events:none; to all other elements of the slider, except of the image-credits. That also didn't work out.
Seems its not workin when you set z-index both parent and child elements. Try to remove z-index from .slider and it should work.
If you specify z-index on an element, it gonna impacts his descendants too. If you specify a negative z-index, then the corresponding elements are going "behind" <body> element. Then all your click are on <body> element. As <body> have a transparent background, you could have the impression click on your link, but you are not.
To be able to click on your link, it should have no element with greater z-index in front. Below, I have made you an example without z-index on .slider (which is one of the ascendants of your link, so it specifies indirectly z-index for him)
.slider {
width: 100%;
position: relative;
height: 600px;
}
.banner {
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.banner-image {
position: fixed;
top: 0;
left: 0;
object-fit: cover;
width: 100%;
height: 640px;
z-index: -2;
}
.image-credits {
background-color: black;
color: white;
padding: 2px 8px;
margin: 10px;
position: absolute;
bottom: 0;
right: 0;
}
.image-credits a {
color: white;
}
<div class="slider">
<div class="banner">
<img class="banner-image" src="https://via.placeholder.com/1280" alt="Description, what you see">
<div class="content">
<h1>Some tagline</h1>
<p class="image-credits">Photo by <a href="#" target="blank">Photographer</a\></p>
</div>
</div>
</div>

Text won't absolutely position using CSS?

I am new to CSS and HTML, and I am working on my final project for school.
I am trying to absolutely position some text "Welcome" to a div I've made. For some reason it won't position in relation to the div, I've looked it over 10 times and can't figure out why.
I want the "Welcome" text to sit at the bottom of the welcome div, however when I put bottom:0px; into the CSS, it doesn't position according to its parent container and instead goes 0px from the top of the whole screen.
Here's the code:
#wrapper {
height: 1000px;
margin: 0 auto;
background-image: url(images/background.jpg);
background-size: 100% 100%;
}
#header {
height: 150px;
position: relative;
background-color: red;
}
#welcome {
position: absolute;
bottom: 0;
width: 420px;
height: 100px;
background-color: green;
}
.w {
height: 150px;
position: absolute;
font-size: 64px;
left: 20px;
bottom: 0px;
color: #fff;
}
<div id="wrapper">
<header id="header">
<div id="welcome">
<p class="w">Welcome</p>
</div>
<nav id="main nav"></nav>
</header>
</div>
You are very close. Take the height away from the .w p tag and remove its margin as well:
#wrapper {
height: 1000px;
margin: 0 auto;
background-image: url(images/background.jpg);
background-size: 100% 100%;
}
#header {
height: 150px;
position: relative;
background-color: red;
}
#welcome {
position: absolute;
bottom: 0;
width: 420px;
height: 100px;
background-color: green;
}
.w {
/*height: 150px;*/
margin: 0;
position: absolute;
font-size: 64px;
left: 20px;
bottom: 0px;
color: #fff;
}
<div id="wrapper">
<header id="header">
<div id="welcome">
<p class="w">Welcome</p>
</div>
<nav id="main nav"></nav>
</header>
</div>
The problem, as CalvinNunes pointed out, is that you have a height set on .w div. And, p elements have margin and line-height values by default. You need to remove the margin and set the line-height to 1 or less (.5 makes the text touch the bottom of the green box).
#wrapper {
height: 1000px;
margin: 0 auto;
background-image: url(images/background.jpg);
background-size: 100% 100%;
position: relative;
}
#header {
height: 150px;
background-color: red;
position: absolute;
width: 100%;
}
#welcome {
position: absolute;
bottom: 0;
width: 420px;
height: 100px;
background-color: green;
}
.w {
position: absolute;
font-size: 64px;
left: 20px;
bottom: 0px;
color: #fff;
margin: 0;
line-height: 1;
}
<div id="wrapper">
<header id="header">
<div id="welcome">
<p class="w">Welcome</p>
</div>
<nav id="main nav">
</nav>
</header>
</div>
<!-- End of wrapper-->
If you use absolute on something, related dom element should be relative, absolute or fixed, depending on your needs.
Also check if your absolute element doesn't have some unneeded margins etc.
But in your usage case i don't think that there is absolute needed. you can use bigger paddings for parent element top. Also this can be achieved using flex-end, which will allow dynamic text input.

css applying margin that is not there in the code

fairly new to web dev. I have a page that has a basic document flow, with images followed by text.
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
body {
background: url(Images_Albums/Background.jpg) no-repeat;
background-size: 100%;
}
article {
margin: 0;
padding: 0;
position: absolute;
width: 32%;
height: 100%;
left: 50%;
transform: translate(-50%, 0);
background: url(Images_Albums/FrontImage.jpg) no-repeat;
background-size: 100%;
}
#container {
margin: 0;
padding: 0;
margin-top: 9%;
position: relative;
width: 43%;
left: 50%;
transform: translate(-50%, 0);
}
img {
max-width: 100%;
}
p {
margin: 0;
padding: 0;
color: white;
font-family: QuaestorSans;
text-align: center;
}
<article>
<div id="container">
<div id="album1" class="albums">
<img src="Images_Albums/Album1.jpg">
<p>[details]</p>
</div>
<div id="album2" class="albums">
<img src="Images_Albums/Album2.jpg">
<p>[details]</p>
</div>
<div id="album3" class="albums">
<img src="Images_Albums/Album3.jpg">
<p>[details]</p>
</div>
</div>
</article>
My issue is that there is space between the images and the text:
I have web inspector with the text element selected and you can see there is a gap between this element and the image above. All my margins and my paddings are 0, so why am I getting this gap? Many thanks!
This space is caused of the image because it's an inline element. To remove the space just add display: block to the img
CSS
img {
max-width: 100%;
display: block;
}
Try adding a 0 margin to your img tag. Many HTML tags have default CSS attached to them which will be applied unless you specifically override it.
img {
max-width: 100%;
margin: 0;
}
You can use display: blockand float: left for img.

Firefox - width: 100% not working as expected

I am building a site that works fine in both Chrome and Safari, but am having difficulties in Firefox. The applicable HTML in this issue is simple, is is just three divs inside of another div. The goal is to have one div positioned at the top of the parent div, one at the bottom, and one stretching across the remaining space:
<div class="outer">
<div class="top">
<p>some junk here</p>
</div>
<div class="middle">
<img src="<?php echo(htmlspecialchars($image_url)); ?>"/>
</div>
<div class="bottom">
<p>more junk</p>
</div>
</div>
Now, the css is as follows:
.outer {
position: relative;
display: inline-block;
text-align: center;
width: 600px;
height: 600px;
}
.middle {
background-size: 100%;
top: 62px;
bottom: 62px;
right: 0;
left: 0;
margin: 0;
padding: 0;
position: absolute;
}
.middle img {
position: absolute;
margin: auto;
top: 0;
left: 0;
right: 0;
bottom: 0;
max-width: 95%;
max-height: 95%;
}
.top, .bottom {
width: 100%; /* THIS IS WHAT IS NOT WORKING */
height: 60px;
margin: 0;
padding: 0;
display: table;
position: absolute;
}
.top {
top: 0;
}
.bottom {
bottom: 0;
}
The issue is that the top and bottom divs are not extending to 100%. The are taking up as little space as necessary to fit their content. I have tried setting a max width on the divs, tried changing the display types, but nothing works. The kicker is, once I resize the window even the smallest amount, the top and bottom divs shoot to 100%. Strange. I am at a loss with this one so any help is greatly appreciated. Thanks.
.outer DIV cannot be display: inline-block for this scenario. inline-block means to adapt to the child widths. You need to either specify an exact width dimension, or use block display property.
.outer {
position: relative;
display: block; /* use BLOCK here instead of inline-block; */
text-align: center;
}
The reason why the top and bottom divs' widths were not working properly was because they were set to a display type of table. Removing just that line fixed the issue.
.top, .bottom {
width: 100%;
height: 60px;
margin: 0;
padding: 0;
/* REMOVE: display: table; */
position: absolute;
}

Constrain table height and image to height of container

I have the following test here: http://dev.driz.co.uk/gallery/index2.php
The idea is that an image should be centred within the gallery div and have 72px of padding all the way around it. If the image is smaller than the screen, then it will be centred (this part works), however if the image is larger than the screen then it should resize itself to fit depending on the best ratio.
This is achieved by setting the image max-height and max-width to 100% so the image is constrained by its container element. And in this case the container is two faked tables with CSS to centre it on the page.
What's actually happening is the image is just ignoring the max-height property and only applying the width constrain, so it appears off the page.
Any ideas on what the issue is? In the past I have just used JavaScript to position the image in the middle, but would prefer to use just CSS like in the example.
Full code is as follows:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Center</title>
<style type="text/css">
*
{
margin: 0;
padding: 0;
border; 0;
}
html,body
{
height: 100%;
width: 100%;
}
body
{
overflow: hidden;
}
.gallery
{
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
}
.gallery-background
{
background: #333333;
top: 0;
left: 0;
right: 0;
bottom: 0;
position: fixed;
padding: 72px;
}
.gallery-outer
{
display: table;
width: 100%;
height: 100%;
border-collapse: collapse;
table-layout:fixed;
}
.gallery-inner
{
text-align: center;
display: table-cell;
vertical-align: middle;
width: 100%;
height: 100%;
}
.gallery-image
{
position: relative;
}
.gallery-image img
{
max-width: 100%;
max-height: 100%;
vertical-align: middle;
}
</style>
</head>
<body class="default">
<div class="gallery">
<div class="gallery-background">
<div class="gallery-outer">
<div class="gallery-inner">
<div class="gallery-image">
<img src="EmpireState.jpg">
</div>
</div>
</div>
</div>
</div>
</body>
</html>
When you give an image a max-height of 100%, it looks for its direct parent tag's height. If that doesn't have a height or constrained in anyway, then it can't apply the rule to height of the image. Looking at your HTML/CSS, I would strip it back and simplify it like this:
<div class="gallery">
<div class="gallery-background">
<img src="EmpireState.jpg">
</div>
</div>
And the CSS
.gallery {
bottom: 0;
height: 100%;
left: 0;
position: fixed;
right: 0;
top: 0;
width: 100%;
}
.gallery-background {
background: none repeat scroll 0 0 #333333;
bottom: 0;
left: 0;
padding: 72px;
position: fixed;
right: 0;
text-align: center;
top: 0;
}
.gallery-background:before {
content: ' ';
display: inline-block;
vertical-align: middle;
height: 100%;
}
.gallery-background img {
max-height: 100%;
max-width: 100%;
vertical-align: middle;
}
Hopefully that should sort it out