"Fixed" positioned before pseudo element - css

How can I make the icon::before pseudo element not scroll. I want it to have a "fixed" position; not relative to the window, but to div.scrollable.icon
Here's the demo I'm talking about: http://codepen.io/anon/pen/VLWdEm
===UPDATE===
There's a problem here. Here's the new codepen: http://codepen.io/kiranm/pen/QbgxZV
How do I make icon::before "fixed" relative to div.scrollable.icon?

Ok, I understood your problem. Since we all tried the code with the preview expanded we didn't see that when we shrink the preview the div was fixed relative to the window.
So I came up with this, although I couldn't do it just with CSS, I had to add a little of jQuery and modify your HTML structure.
HTML
<div class="scrollable">
<div class="icon"></div>
text
</div>
CSS
.scrollable {
border: 1px solid tomato;
width: 200px;
height: 200px;
overflow: auto;
position: absolute;
}
.icon {
position: relative;
}
.icon::before {
content: 'An icon';
background-color: yellow;
padding: 2em;
}
And the jQuery
var $ = jQuery || $;
$(document).ready(function() {
$('.scrollable').on('scroll', function() {
var top = $('.scrollable').scrollTop() + $('.scrollable').offset().top;
$('.icon').css({'top': top + 'px'});
});
});
As you can see I added another CSS rule so I can manipulate it with jQuery, and with jQuery I took the value of the scroll in the container div and I add to it its value to the top of the window, and I assign that result to the top of the icon so it will be "fixed" to the div. Also I moved the icon div to be a child of scrollable so I can manipulate it separately.
Here's the pen http://codepen.io/anon/pen/QbgxzV
I hope it helps you.

Try like this: Demo
.icon::before {
content: 'An icon';
background-color: yellow;
padding: 2em;
position: fixed; / * changed position absolute to fixed */
}

I cant understand your requirement?
Position fixed is working for relative to window screen only. otherwise you set icon position:relative then give icon::before position absolute.

Related

Inheriting Width when child is position fixed

I am trying to have a header div inherit it's width from it's parent.
The header div is position fixed.
However, as you can see in the simple PLNKR i've created here:
http://plnkr.co/edit/wxcvssALhjxtzc7J4w3V
it is actually wider than it's parent element, which is very weird.
The html looks like this:
<div class="category-body">We are in the category-body
<div class="category-header">We are in the category-header</div>
</div>
And the CSS looks like this:
.category-body {
margin-left: 17% !important;
width: 67%;
background-color: red;
height: 500px;
}
.category-header {
position: fixed;
top: 51px;
width: inherit;
background-color: green;
}
Any ideas why this is happening? And, of course, how to fix it?
You are not using a reset css sheet so probably the browser's body margin by default is messing with your code. It will affect your parent as the position is static but it will NOT affect your fixed child as fixed elements get out of the html flow.
just add:
html, body {margin:0;}
FIDDLE

CSS - Position footer relative to body's bottom

I might me using the terms absolute and relative wrong, but hopefully you get what I mean. I want to give my footer some "bottom: 10px" so that it stays at the bottom of the page, no matter if the page's content is more or less than 100% of the browser window. I tried positioning it absolute but it will be positioned relative to the browser window then, not the body.
This is an example: http://public-demo.webflow.com
Any ideas? Thank you :)
add this to the body
position: relative
and add this to the footer
position: absolute
This way the footer will be positioned accordingly to the body
It would be good if you set the bottom to 0px.
If you want to fix this kind of problem, you can inspect your element with Mozilla, and play your code there.
FOOTER TO STICK BOTTOM IF CONTENT IS SMALLER THAN THE VIEWPORT and BEHAVE NORMAL IN OTHER CASE
You'll need a tiny JS for that.
$(function () {
var bht = $('body').height();
var wht = $(window).height();
if (bht < wht) {
$('#footer').css("position", "absolute");
$('#footer').css("bottom", "10px");
}
});
Check this fiddle - http://jsfiddle.net/3N4L9/4/
FOOTER TO STICK TO BOTTOM IN ANY CASE
This will generate same output as required :
Like page 1 : http://jsfiddle.net/3N4L9/1/
Like page 2 : http://jsfiddle.net/3N4L9/2/
It'll keep footer on the bottom of page irrespective of content and scroll.
.fixedFooter{
width:100%;
position:fixed;
bottom:10px;
}
That should work
.footer-text {
background-color: rgba(0, 0, 0, 0.49);
bottom: 10px;
color: white;
left: 0;
margin-top: 10px;
position: absolute;
right: 0;
text-align: center;
z-index: 999;
}

Can a child of #map-canvas be in front of the map?

I am trying to get a div, which is a child of #map-canvas, in front of the map.
At first, I changed the name of the parent to #maps-canvas, so the map wouldn't appear anymore.
I changed different CSS parameters and it worked perfectly. Then I changed the div back to #map-canvas (I also changed the id in my CSS file), so the map would appear again.
Interestingly, the child div disappeared. Then I added a z-index (child: 100, parent: 1), but still no change.
Here's the code:
HTML <div id="map-canvas">
<div id="TEXT13"></div>
</div>
CSS #map-canvas
width:100%;
height:93%;
top:7%;
z-index:1;
CSS #TEXT13
top: 70%;
left:40%;
height: 30%;
width: 20%;
background-color: blue;
border: 1px solid black;
position:relative;
z-index: 900;
Am I doing something wrong or is the Google-code preventing the div to be in front of the map?
"You cannot place elements inside a canvas (and have both displayed); they are only displayed if the browser does not understand the canvas element."
Placing a <div> within a <canvas>
You'd have to implement something like Andys answer to get the same effect. (Absolute positioning)
I would suggest that instead of putting the element inside #map-canvas as a child, you put it before #map-canvas as an absolute positioned element. Then set the z-index above the #map-canvas. This will allow it to act as an overlay on top of the map.
Css example:
#something_you_want_on_top_of_map {
width: 300px; /* set to same size as map */
height: 300px;
position: absolute;
z-index: 100;
}
Html example:
<div id="something_you_want_on_top_of_map">content...</div>
<div id="map-canvas"></div>
Hope that helps!

Is it possible to keep the width of the parent element when position: fixed is applied?

When we apply position:fixed to an element, it's taken out of the normal flow of the document, therefore it doesn't respect it's parent's element width.
Are there ways to make it inherit it's parent's width if this is declared as a percentage ? (working use case below)
let widthis = $('.box').width();
$('.dimensions').text(`width is ${widthis}`);
$('button').on('click', function() {
$('.box').toggleClass('fixed');
let widthis = $('.box').width();
$('.dimensions').text(`width is ${widthis}`);
});
.container {
max-width: 500px;
height: 1000px;
}
.box {
background-color: lightgreen;
}
.fixed {
position: fixed;
}
.col-1 {
border: 1px solid red;
float: left;
width: 29%;
}
.col-2 {
border: 1px solid pink;
float: left;
width: 69%;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>Click this to toggle position fixed for the left column</button>
<div class="container">
<div class="col-1">
<div class="box">
fixed content<br>
<span class="dimensions"></span>
</div>
</div>
<div class="col-2">
some other content
</div>
</div>
This is an interesting challenge. To approach this, we should first understand what fixed actually does.
Understand Fixed
Unlike absolute, fixed doesn't position itself from its closest relative parent. Instead, fixed positions itself relative to the viewport. The viewport will always stay fixed, which is why you get the effect that you do.
That being said, whenever you "inherit" any width it will be respective to the viewport. So it does us no good when we're trying set the width of our target element to the width of it's parent.
Learn more about the different behaviors of position.
Quick Solutions
There are two approaches to fix this.
Pure CSS
We can use pure CSS to fix this problem, but we would need to know the width in advance. Suppose that its parent element is 300px;
.parent{
width: 300px;
}
.parent .fixed_child{
position: fixed;
width: 300px;
}
JS
Now with mobile devices, we don't really have the luxury of having set widths, especially anything over 300px. Using percentages won't work either, since it will be relative to the viewport and not the parent element. We can use JS, in this case with jQuery to achieve this. Lets take a look at a function that will always set the width of the parent at the given moment:
function toggleFixed () {
var parentwidth = $(".parent").width();
$(".child").toggleClass("fixed").width(parentwidth);
}
css:
.fixed{
position:fixed;
}
View in CodePen
Dynamic Widths
That's fine and dandy, but what happens if the width of the window changes while the user is still on the page, changing the parent element with this? While the parent may adjust its width, the child will stay the set width that the function set it. We can fix this with jQuery's resize() event listener. First we'll need to split the function we created into two:
function toggleFixed() {
adjustWidth();
$(".child").toggleClass("fixed");
}
function adjustWidth() {
var parentwidth = $(".parent").width();
$(".child").width(parentwidth);
}
Now that we've separated each part, we can call them individually, we'll include our original button method that toggles the fixed and width:
$("#fixer").click(
function() {
toggleFixed();
});
And now we also add the resize event listener to the window:
$(window).resize(
function() {
adjustWidth();
})
View in CodePen
There! Now we have a fixed element who's size will be adjusted when the window is resized.
Conclusion
We've tackled this challenge by understanding fixed position and it's limitations. Unlike Absolute, fixed only relates to the view port and therefore cannot inherit its parent's width.
To solve this, we need to use some JS magic, which didn't take very much with jQuery, to achieve this.
In some cases, we need a dynamic approach with scaling devices of varying widths. Again, we took the JS approach.
You can use width:inherit. This will make it listen to parent. I test it and it works in Firefox.
The width is changing because the object when static is receiving its percentage width from its parent. Once you set the object to fixed it is no longer in flow and resizes.
You're gonna have to set a size to your nav menu on its own and not expect the element to get its width from the parent.
.nav {
position: fixed;
width: 20%;
border: 1px solid green;
padding: 0px;
list-style-type:none;
background:lightblue;
}
http://tinker.io/3458e/5
Hi you could also use jquery to keep the width. For example:
jQuery(function($) {
function fixDiv() {
var $cache = $('#your-element');
var $width = $('#your-element').parent().width();
if ($(window).scrollTop() > 100) {
$cache.css({
'position': 'fixed',
'top': '10px',
'width': $width
});
} else {
$cache.css({
'position': 'relative',
'top': 'auto'
});
}
}
$(window).scroll(fixDiv);
fixDiv();
});
As someone already suggest, using plain javascript (without jquery):
const parentElement = document.querySelector('.parent-element');
const fixedElement = document.querySelector('.fixed-element');
window.addEventListener('load', changeFixedElementWidth);
window.addEventListener('resize', changeFixedElementWidth);
function changeFixedElementWidth() {
const parentElementWidth = parentElement.getBoundingClientRect().width;
fixedElement.style.width = parentElementWidth + 'px';
}
This is likely because of some default margin or padding on the <html> or <body> element. When it's static, it sizes based on the <body>'s width at the time, but when it changes to position:fixed it's sized in respect to the viewport.
As such, removing that default margin/padding should fix the problem (in my experience body { margin:0; } fixes it) as should changing the sizing when it is fixed (like width:calc(n% - 5px);).
A workaround might be: left:8px; right:0; width:18%; in the CSS for the nav.
Not the best solution though.
In my case, I wanted a responsive UI, but I also want a fixed sidebar. What I did was find the maximum width on the largest screen in pixels (250px in my case). Then I used:
<script>
.parent {
maxWidth: '1500px';
margin: 'auto auto';
}
.left {
flex: 1;
}
.center {
flex: 4;
}
.right {
flex: 1;
}
.fixedTop {
position: 'fixed';
maxWidth: '250px';
}
</script>
<div className="parent">
<div className="left">left side</div>
<div className="center">center</div>
<div className="right">
<div className="fixedTop">
<label>I am responsively sized horizontally up to my max width.</label>
</div>
</div>
</div>
This does not allow you to inherit width as requested, but it may help avoid that need if you are trying to do what I did.
I was here on this thread at first, but my problem was not solved, so I did a work around myself amnd it worked in my case. here it is..
`
.parent{
position: "sticky";
top, right, bottom, left: // adjust distance from sides so that it will be like in fixed position
}
.child{
width:"100%"
}
`
Add width:auto; to the element with position:fixed; to make its width equal to the width of its parent element.

CSS - how to hide the top of a container using CSS-height, vertical-align and overflow?

I have an image container based on Jquery Mobile listview element structure.
Looks like this:
<li>
<div class="ui-btn-inner">
<div class="ui-btn-text">
<a>
<img src="img/products/l/demo2.jpg">
<h3>product2</h3>
</a>
</div>
</div>
</li>
I'm overriding JQM-CSS to create an image gallery-list. Images and h3 are both contained inside a link element. As the images can have different heights, I want to set a CSS fixed-height/overflow:hidden to the link element to cut off images at the top using vertical align: top.
Here is my CSS so far:
li {
display: inline-block;
min-width: 200px;
max-width: 300px;
width: 24%;
}
li img {
width: 100%;
position: static !important;
max-width: 185px;
max-height: inherit;
}
// fix height and overflow hidden
li a {
height: 100px;
overflow: hidden;
vertical-align: bottom;
}
It doesn't work... If I check on Firebug, the element-height is set to 100px, but it covers the image top versus covering the image bottom and h3, which I do not want to crop away.
I have tried setting line-height to 100px as well, but this does not work at all.
Any hints on what I'm doing wrong?
Thanks!
EDIT:
Can't use clip either, because I don't know at what height I want to start (img.height-100px) and I cannot clip from the bottom. Or can I?
SOLUTION:
It would work like this:
li a {
position:absolute;
bottom: 0;
left: 0;
}
li div.ui-btn-text {
position: relative;
height: 100px;
overflow: hidden;
}
Doesn't use vertical-align but the result is ok.
I'm afraid that can't work. Adding display:block; to your link and would be a start for your method, but check the result: http://jsfiddle.net/uu96D/
vertical-align: bottom; won't push the a tag to the bottom of the container. Here is a guide of how vertical-align works: http://phrogz.net/css/vertical-align/index.html
To solve your problem i'd go to some js solution, and add a negative top margin to the image if its taller than, for example, 80px. Here's a fiddle with the result: http://jsfiddle.net/uu96D/1/
And the code using jQuery:
$('img').each(function(){
var height = $(this).height();
if (height > 80) {
$(this).css({marginTop: "-" + (height-80)});
}
});

Resources