Using position:absolute while keeping it inside the document flow - html

It's a screenshot from a page currently I'm building. I'm trying to make sure the green button is always on the bottom of the container. Here is a piece of the code:
HTML
<div class="list-product-pat">
<article>
<!-- title, image, spec ... -->
<div class="pricing-pat">
<!-- the button goes here -->
</div>
</article>
</div>
CSS
.list-product-pat article {
position: relative;
min-height: 260px;
}
.list-product-pat .pricing-pat {
position: absolute;
bottom: 0;
width: 100%;
}
So far there is no problem... until the product spec gets too long and it breaks into the green button.
I want to maintain the green button in the most bottom position, but in the same time I also want the height to extend if the product title/product spec gets too long.
In the ideal world, it should be something like this:
So my idea is to maintain the absolute positioning while still keeping it inside the document flow (so the product spec knows the green button is there and doesn't break through it).
I need it only to extend if the spec height gets too long. In other words, if the spec is in normal height, it wouldn't extent. I'd like to avoid a weird gap between the spec and the green button.
Is there any idea how to do it?
Here is a fiddle to see how I did it: http://jsfiddle.net/xaliber/xrb5U/

Adding position:absolute takes it out of the document flow, there's no way to keep it in it.
But you can add padding-bottom equivalent to height of the button to the article container instead, which will prevent long text overrunning the button.
.list-product-pat article {
position: relative;
min-height: 260px;
padding-bottom:80px;
-moz-box-sizing:border-box;
box-sizing:border-box;
}
http://jsfiddle.net/xrb5U/3/
A separate issue is that two containers with different amount of texts will be different sizes (if one is larger than the min-height set). There's no easy fix for this in CSS positioning, you have to resort to Javascript, Flexbox or display:table-cell to keep the height of all them the same but each of them has their own issues too.

As #mikel already pointed out, you can't keep an element with position: absolute inside the normal document flow, but you can workaround this problem by simulating it.
Considering the example below:
img {
position: absolute;
}
<img src="https://dummyimage.com/300x400/d9ca29/ffffff">
<span>Lorem Ipsum is simply dummy text of the printing and typesetting industry</span>
The <img> element is out of flow, this cause the <span> to be hidden behind it.
You can wrap the absolute element inside an empty container, then add height and width to container equal to height and width of the absolute element. By doing so, an invisible box is created around the absolute element, which makes it appear as part of the document normal flow.
If you already know the exact dimensions of the <img> element, you can simulate normal flow using just css:
div {
border: 2px dotted grey;
position: relative;
width: 300px;
height: 400px;
}
img {
position: absolute;
}
<div>
<img src="https://dummyimage.com/300x400/d9ca29/ffffff">
</div>
<span>Lorem Ipsum is simply dummy text of the printing and typesetting industry</span>
Else, if you don't know the dimensions of the absolute element upfront you have to simulate the normal flow dynamically with javascript:
window.addEventListener('load', function() {
var div = document.querySelector('div');
var img = document.querySelector('img');
var rect = img.getBoundingClientRect();
div.style.height = rect.height + 'px';
div.style.width = rect.width + 'px';
});
div {
border: 2px dotted grey;
position: relative;
max-width: 200px;
}
img {
position: absolute;
width: 100%;
}
<div>
<img src="https://dummyimage.com/300x400/d9ca29/ffffff">
</div>
<span>Lorem Ipsum is simply dummy text of the printing and typesetting industry</span>

At some point in the (hopefully near) future, you'll be able to use the subgrid feature of CSS Grids. Currently, only Firefox supports this, but other browsers should add support soon.
Subgrid enables you to use Grid features with a non-flat structure (eg, an unordered list). That is, you can line up children of one element with children of another element, or in this case, the image, title, description, and price button.
.list-product-pat {
/* Create a grid with 5 columns that are 175px wide,
each with 5 rows that are sized based on the smallest item in the row */
display: inline-grid;
grid-template-columns: repeat(5, 175px);
grid-template-rows: repeat(5, min-content);
/* Colors and spacing to match design */
background: #f4f4f4;
padding: 1em;
grid-column-gap: 1em;
border: 1px solid #ddd;
}
.list-product-pat li {
/* Ensure this item takes up the column */
grid-row: 1 / -1;
/* Make children grid items */
display: grid;
/* Use parent's grid for children */
grid-template-rows: subgrid;
/* Styles to match design */
text-align: center;
justify-items: center;
border: 1px solid #ddd;
background: #fff;
}
/* STYLES TO MATCH DESIGN BELOW */
.list-product-pat > li > img {
margin-top: 1em;
}
.list-product-pat > li > h1 {
margin: .8em 0;
font-size: 1em;
}
.list-product-pat > li > p {
margin: 0;
color: #bbb;
font-size: .8em;
margin: 0 .5em 1em;
}
.list-product-pat > li > a {
text-decoration: none;
color: white;
font-weight: bold;
background: linear-gradient(#60bb76, #48b161);
border-radius: .5em;
box-shadow: 1px 1px 2px rgba(0, 0, 0, .5);
padding: .5em;
min-width: calc(100% - 1em);
margin-bottom: .5em;
box-sizing: border-box;
}
.list-product-pat > li > a > small {
display: block;
font-weight: normal;
font-size: .7em;
margin-top: .2em;
}
<ul class="list-product-pat">
<li>
<img src="https://placehold.it/40x70/">
<h1>HTC Desire C</h1>
<p>GSM, GPS, WiFi, kamera 5MP, bluetooth, Android, touchscreen, 600MHz</p>
1.699.000 <small>6 Produk/4 Website</small>
</li>
<li>
<img src="https://placehold.it/40x70/">
<h1>Samsung 19300 Galaxy S III</h1>
<p>GSM, GPS, WiFi, kamera 8MP, bluetooth, Android, touchscreen, 1.4GHz</p>
5.300.000 <small>8 Produk/5 Website</small>
</li>
<li>
<img src="https://placehold.it/40x70/">
<h1>Samsung Galaxy Grand i9082</h1>
<p>GSM, GPS, WiFi, touchscreen, 1.2GHz</p>
3.499.000 <small>10 Produk/8 Website</small>
</li>
<li>
<img src="https://placehold.it/40x70/">
<h1>Apple iPhone 5 16GB</h1>
<p>GSM, GPS, WiFi, kamera 8MP, bluetooth, iOS 6, touchscreen, 1.2GHz</p>
7.599.000 <small>6 Produk/5 Website</small>
</li>
<li>
<img src="https://placehold.it/40x70/">
<h1>BlackBerry Curve 9360 (Apollo)</h1>
<p>GSM, GPS, WiFi, kamera 5MP, bluetooth, 800MHz</p>
225.000 <small>9 Produk/4 Website</small>
</li>
</ul>

The solution is actually quite simple. Duplicate the absolutely positioned footer with visibility hidden.
<div style="background: silver; position: relative; height: 100px">
Height is 100px
<div style="position: absolute; bottom: 0; left: 0">Footer</div>
<div style="visibility: hidden">Footer</div>
</div>
<br />
<div style="background: silver; position: relative">
No height specified
<div style="position: absolute; bottom: 0; left: 0">Footer</div>
<div style="visibility: hidden">Footer</div>
</div>

Related

styling on element inside nested :visited declaration not being applied (vuejs, sass)

Really confused by this one. I have a grid of items with a link to wrap the image, an image overlay div, and a title. When the link is visited, the nested image overlay should change its background color opacity. But it's not being applied. I can verify that the :visited pseudoclass is taking effect, because it will apply color change to the nested title. But the opacity won't change. I've tried numerous methods of applying it. Here's a pen:
https://codepen.io/heaversm/pen/gOYNJQv
HTML
<div class="gallery__container">
<div class="gallery__item">
<a class="gallery__link" href="http://codepen.io">
<div class="gallery__image_container">
<img src="https://i.imgur.com/MQcuk3n.jpg">
<div class="gallery__overlay"></div>
</div>
<p class="gallery__title">Title</p>
</a>
</div>
<div class="gallery__item">
<a class="gallery__link" href="http://nonsensesite.com">
<div class="gallery__image_container">
<img src="https://i.imgur.com/MQcuk3n.jpg">
<div class="gallery__overlay"></div>
</div>
<p class="gallery__title">Title</p>
</a>
</div>
</div>
CSS
.gallery__container {
display: grid;
grid-template-columns: repeat(5, 1fr);
grid-gap: 1.375vw;
margin: 0 auto;
padding: 40px 50px;
}
.gallery__image_container {
position: relative;
}
.gallery__item {
width: 100%;
height: auto;
}
.gallery__link {
display: block;
width: 100%;
height: 100%;
&:visited {
color: red; //just to verify visited pseudoclass is applied
.gallery__overlay {
background-color: rgba(0,0,0,.1) !important; //NOT WORKING
}
}
}
.gallery__image {
//width: 100%;
//height: auto;
}
.gallery__overlay {
display: block;
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
background-color: rgba(black, 0.9);
z-index: 1;
}
From https://developer.mozilla.org/en-US/docs/Web/CSS/:visited
For privacy reasons, browsers strictly limit which styles you can apply using this pseudo-class, and how they can be used:
Allowable CSS properties are
color, background-color, border-color, border-bottom-color, border-left-color, border-right-color, border-top-color, column-rule-color, and outline-color.
Allowable SVG attributes are fill and stroke.
The alpha component of the allowed styles will be ignored. The alpha component of the element's non-:visited state will be used instead, except when that component is 0, in which case the style set in :visited will be ignored entirely.
Although these styles can be change the appearance of colors to the end user, the window.getComputedStyle method will lie and always return the value of the non-:visited color.
And from my own observation, child elements of a link are also subject to the same styling restrictions.

linkable image with a mouseover text

I wanted to make this linkable image to have a text in a pop up box (not the type of pop up that is on w3schools, I want a classic yellowish box) when I mouseover. I tried to do it like this
<div class="folder1">
<a href="yourlinkhere" target="_self" >
<img src="https://78.media.tumblr.com/c00202bad8ae39931e34a7efa861d18b/tumblr_p70bjja6xI1x5vw3ao1_500.png" height="46" width="57"
title="This is some text I want to display." </a>
</div>
Opening the page in the link works great but there is no pop up box when I hover on it. Any help?
Currently, you are setting the title attribute to get a tooltip type hint when the element is hovered over. If this is what you are looking to do but perhaps just style the textbox to be, say, yellow, I would suggest using the following:
a {
color: #900;
text-decoration: none;
}
a:hover {
color: red;
position: relative;
}
a[data]:hover:after {
content: attr(data);
padding: 4px 8px;
color: rgba(0,0,0,0.5);
position: absolute;
left: 0;
top: 100%;
white-space: nowrap;
z-index: 2;
border-radius: 5px ;
background: rgba(0,0,0,0.5); /*Change this to yellow, or whatever background color you desire*/
}
<a data="This is the CSS tooltip showing up when you mouse over the link"href="#" class="tip">Link</a>
The above code was provided by Peeyush Kushwaha in this post. Simply change the anchor tag to your image tag, and apply styles as you see fit.
If by 'popup' you are looking for an alert to the user that requires interaction to close, you can use window.alert('text') in javascript in conjunction with the onmouseover event handler.
<img src="some_image.png" height="46px" width="57px" onmouseover="window.alert('Some Message')"/>
Otherwise, if you are looking for another element to be displayed upon mouseover of the image, you can use a bit of javascript to display a div or paragraph (really anything) upon mouseover of the img.
function showDiv() {
document.getElementById('popupBox').style.display = 'block';
}
#popupBox {
display: none;
}
<img src="some_image.png" width="41px" height="57px" onmouseover="showDiv()"/>
<div id="popupBox">Some Popup Text</div>
You can do this simply with CSS, or you can use one of many simple 'tooltip' JavaScript options. Bootstrap for example has this tooltip functionality built-in, ready to use. If you want something basic, here's a simple CSS-only approach that you can customise to your needs:
<!-- padding added here so you can see the pop-up above the folder, not necessary in-page -->
<div class="folder1" style="padding: 200px;">
<a href="yourlinkhere" target="_self" class="popper">
<img src="https://78.media.tumblr.com/c00202bad8ae39931e34a7efa861d18b/tumblr_p70bjja6xI1x5vw3ao1_500.png" height="46" width="57" />
<span class="pop-up">This is some text I want to display.</span>
</a>
</div>
<style>
a.popper {
display: inline-block;
position: relative;
}
.pop-up {
display: none;
position: absolute;
left: 0;
bottom: 100%;
padding: 1rem 1.5rem;
background: yellow;
color: black;
}
a.popper:hover .pop-up,
a.popper:focus .pop-up {
display: block;
}
</style>
Basically, you position the a tag relatively so that it can have absolutely positioned children, then relying on a:hover you show / hide the child using the child element's display property.
You can equally try this using css pseudo-element
a{
position: relative;
}
a:hover:after{
display:block;
content: "This is some text I want to display";
width: 200px;
background: yellow;
position: absolute;
top:0;
padding: 20px;
}
<div class="folder1" style="margin: 70px">
<a href="yourlinkhere" target="_self" class="">
<img src="https://78.media.tumblr.com/c00202bad8ae39931e34a7efa861d18b/tumblr_p70bjja6xI1x5vw3ao1_500.png" height="46" width="57"
</a>
</div>

Relative positioning to an absolutely positioned element

I am experimenting with single-page design, and have built a page out of a number of different pages, by essentially creating a column of <div> elements each at 100% of the window height, and positioned absolutely one under another.
Each page, therefore, requires it's elements to be set absolutely, since there is (as far as I can tell) no normal document flow to follow. However, when it comes to text, I am finding it difficult to design. I'd like to try and keep the current design, rather than start over.
On a particular page, I have a text container. In that container, there are two titles. The first title heads two small paragraphs, the second heads one:
HTML
<div id="introTextContainer">
<div id="introTextHeader" class="blurbheader">First title</div>
<div id="introText" class="blurb">
Generic text about the roots of the company
</div>
<div id="introTextParg2" class="blurb">
further information about the roots
</div>
<div id="introStatement1" class="blurb StrongStatement">
Second title
</div>
<div id="introTextParg3" class="blurb">
Eye-catching mission statement
</div>
</div>
CSS
.blurb {
font-family: Lato;
font-size: 16px;
padding-right:10px;
font-size: 1.4vh
}
.blurbheader {
font-family: Lato;
font-size: 2vh;
padding-right:10px;
}
.StrongStatement {
font-family: Lato;
font-size: 20px;
}
#introTextContainer {
height: 20%;
width: 45%;
background: rgba(255,255,255,0.8);
position: absolute;
left: 200px;
top: 10%;
border-radius: 5px;
}
#introTextHeader {
position: absolute;
width: 280px;
left: 30px;
top: 5px;
height: 10%;
}
#introText {
position:absolute;
left: 10px;
font-family: Lato;
}
#introTextParg2 {
position:absolute;
left: 10px;
}
#introStatement1 {
position:absolute;
left: 30px;
}
#introTextParg3 {
position:absolute;
left: 10px;
}
At a standard resolution of 1080p, all of this looks perfectly acceptable. However, when the resolution is changed, the design is not responsive to the same. As you can see with the CSS, I have been experimenting with viewport-height for the text, however the spacing and height of the <div> elements is a different matter.
How can I create a positioning/size context within the scope of the text containers, in order that I can set the height and padding of the text paragraphs therein, within the scope of those containers? The current approach uses javascript, but I don't like the idea of attempting to use javascript to target every screen size possible as this would result in a lot of spaghetti code. Ideally, I would like to use javascript only to set the heights of the "page" <div> elements and the containing boxes.
edit: CSS, JS, HTML of page design
The first page is given a width and height of 100%. The subsequent pages are altered with JQuery. The value data-section-name is used in the seamless scrolling plugin. The canvas is used only to house the background image:
HTML
<section id="pageOne" class="panel pageone" data-section-name="sectionpageOne"> <!-- About -->
<canvas id="pageOneCanvas"></canvas>
<div id="introTextContainer">
<div id="introTextHeader" class="blurbheader">First title</div>
<div id="introText" class="blurb">
Generic text about the roots of the company
</div>
<div id="introTextParg2" class="blurb">
further information about the roots
</div>
<div id="introStatement1" class="blurb StrongStatement">
Second title
</div>
<div id="introTextParg3" class="blurb">
Eye-catching mission statement
</div>
</div>
</div>
</section>
CSS
#pageOne {
position: absolute;
/*top: 0;*/
left: 0;
width: 100%;
}
#pageOneCanvas {
height: 100%;
width: 100%;
z-index: 1;
background-image: url("/Resources/images/aboutcanvas.jpg");
background-size: cover;
opacity: 0.6
}
JS
// Canvas height and positioning
var posheight = $(window).height();
$("#home").height(posheight);
$("#pageOne").height(posheight);
$("#pageTwo").height(posheight);
$("#pageThree").height(posheight);
$("#pageFour").height(posheight);
$("#pageFive").height(posheight);
$("#pageOne").css("top", posheight);
$("#pageTwo").css("top", (posheight * 2));
$("#pageThree").css("top", (posheight * 3));
$("#pageFour").css("top", (posheight * 4));
$("#pageFive").css("top", (posheight * 5));
Additionally, the current solution for fixing the text container dimensions is also in JS. You can start to see why I want to achieve this in CSS, as it's becoming messy here:
var introTextTitleHeight = $("#introTextHeader").height();
$("#introText").css("top", (introTextTitleHeight + 10));
$("#introTextParg2").css("top", ($("#introText").position().top + $("#introText").height() + 10));
$("#introStatement1").css("top", ($("#introTextParg2").position().top + $("#introTextParg2").height() + 10));
$("#introTextParg3").css("top", ($("#introStatement1").position().top + $("#introStatement1").height() + 10));
Would removing position: absolute; on the child divs not do what you want?
And use margin-left instead of left.
So the rules would look like this:
#introTextHeader {
margin-left: 30px;
margin-top: 5px;
height: 10%;
}
#introText {
margin-left: 10px;
font-family: Lato;
}
#introTextParg2 {
margin-left: 10px;
}
#introStatement1 {
margin-left: 30px;
}
#introTextParg3 {
margin-left: 10px;
}

CSS notification style badge over image

I'm attempting to place a 'notification' style badge over an images. I am using Twitters Bootstrap as a base framework and creating a custom CSS class called notify-badge. But I cannot get anything to line up properly.
Through the magic of Photoshop, here is what I am trying to accomplish.
Here is my CSS code.
.notify-badge{
position: absolute;
background: rgba(0,0,255,1);
height:2rem;
top:1rem;
right:1.5rem;
width:2rem;
text-align: center;
line-height: 2rem;;
font-size: 1rem;
border-radius: 50%;
color:white;
border:1px solid blue;
}
I would like to be able to place any small about of text in the badge and it expand the red circle to fit.
Here is my HTML code.
<div class="col-sm-4">
<a href="#">
<span class="notify-badge">NEW</span>
<img src="myimage.png" alt="" width="64" height="64">
</a>
<p>Some text</p>
</div>
Bunch of different ways you can accomplish this. This should get you started:
.item {
position:relative;
padding-top:20px;
display:inline-block;
}
.notify-badge{
position: absolute;
right:-20px;
top:10px;
background:red;
text-align: center;
border-radius: 30px 30px 30px 30px;
color:white;
padding:5px 10px;
font-size:20px;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<div class="col-sm-4">
<div class="item">
<a href="#">
<span class="notify-badge">NEW</span>
<img src="https://picsum.photos/200" alt="" />
</a>
</div>
</div>
Addendum (from the Asker #user-44651)
(moved from the question)
Here is the result of applying this answer.
Adding margin-top:-20px; to .item fixed the alignment issue.
The idea here is to overlay an absolute container on top of a relative one. Here's a similar example:
<div class="image">
<img src="images/3754004820_91a5c238a0.jpg" alt="" />
<h2>A Movie in the Park:<br />Kung Fu Panda</h2>
</div>
The CSS:
.image {
position: relative;
width: 100%; /* for IE 6 */
}
h2 {
position: absolute;
top: 200px;
left: 0;
width: 100%;
}
This is going to put our text right up on top of the image nicely, but it doesn't accomplish the box we want to achieve behind the text. For that, we can't use the h2, because that is a block level element and we need an inline element without an specific width. So, wrap the h2 inside of a span.
<h2><span>A Movie in the Park:<br />Kung Fu Panda</span></h2>
Then use that span to style and text:
h2 span {
color: white;
font: bold 24px/45px Helvetica, Sans-Serif;
letter-spacing: -1px;
background: rgb(0, 0, 0); /* fallback color */
background: rgba(0, 0, 0, 0.7);
padding: 10px;
}
For ideas on how to ensure proper spacing or to use jQuery to cleanup the code a bit by allowing you to remove some of the tags from the code and jQuery them back in, check the source.
Here's a fiddle I made with the sample code:
https://jsfiddle.net/un2p8gow/
I changed the notify-badge span into a div. I saw no reason it had to be a span.
I changed the position to relative. Edit - you could actually keep the attribute position: absolute; provided you know what you're doing with it. Guy in the comments was right.
You had the attribute right: 1.5rem; and I simply changed it to left because it was being inset in the opposite direction of your example.
You can tweak it further but in a vacuum this is what you want.

Table: how to change pictures on mouseover on single rows?

I'm working on a website and I've to create a table with a mouse over effect the effect is only when you go with the mouse on the picture and only on the PDF icon.
What I need now is to apply this effect when you go with the mouse on the single table rows. How can I do it?
HTML:
<td class="thumbnail-item" data-th="PDF"><img src="http://salmenpark-test.nowcommu.myhostpoint.ch/wp-content/uploads/2015/07/pdf.png" alt="PDF" height="24" width="24">
<div class="tooltip">
<img src="qh_1.png" alt="" width="570" height="403" />
<span class="overlay"></span>
<span class="overlay"></span>
</div></td>
CSS :
.thumbnail-item {
/* position relative so that we can use position absolute for the tooltip */
display: inherit;
height: 10px;
max-width: 5px;
}
.thumbnail-item a {
display: block;
}
.tooltip {
/* by default, hide it */
display: none;
/* allow us to move the tooltip */
position: absolute;
/* align the image properly */
padding: 8px 0 0 8px;
z-index: 500;
top: 7px;
left: -8px !important;
max-width: 570px !important;
max-height: 403px !important;
Antionio:
CSS:
.thumbnail-item {
/* delete the line that was here for inheriting the display * /
height: 10px;
max-width: 5px;
}
HTML:
<tr class="thumbnail-item white">...</tr>
<tr class="thumbnail-item grey">...</tr>
etc, etc.
You were adding the "thumbnail-item" css reference to the <td>tag which represents a cell of data. You want the "thumbnail-item" css reference to be on the entire row, so it should be on each <tr> tag instead.
In your Jquery code, use the class of your td.hover function and try with the below code.
$(".thumbnail-item").hover(function() {
//Write your js code what you have written for hover pdf image
});
It would be better for us to understand if you post your jquery code as well.