Clipping fixed elements in IE/Edge - css

For a page on a site I am building, I have implemented an effect where I have a grid of tiles, and the contents of each tile is fixed to the page (position: fixed) and only visible when the tile containing it "scrolls past". So, all tile contents are effectively piled on top of each other at the top of the page, but are clipped from view until the parent element overlaps it.
To briefly explain the technique, tiles are relatively positioned and contain an absolutely positioned element with a clip rectangle, which in turn contain the fixed element.
However, it does not render properly in IE/Edge; when the page initially loads it looks fine, but when scrolling, the clipped tile contents don't appear when they should. It works fine in Chrome, Firefox, and Safari (actually, the same issue occurs in Safari util transform: perspective(0); is added to the tile contents). It seems that IE "forgets" to render the tile contents, and only does so when the window is resized or some other page-wide event occurs that requires it to recalculate all elements.
body {
margin: 0;
padding: 0;
}
ul {
margin: 0;
padding: 0;
}
ul li {
margin-top: 10%;
position: relative;
border: 1px solid green;
}
ul li, ul li > div > div a {
width: 35%;
height: 0;
padding-bottom: 25%;
display: block;
}
ul li:nth-child(odd) {
clear: both;
float: left;
margin-left: 10%;
}
ul li:nth-child(even) {
float: right;
margin-right: 10%;
}
ul li > div, ul li > div > div {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
ul li > div > div {
clip: rect(0, auto, auto, 0);
}
ul li a {
top: 0;
margin-top: 10%;
position: fixed;
background-color: #000;
color: #fff;
transform: perspective(0); /* necessary for Safari */
}
ul li:nth-child(odd) a {
left: 10%;
}
ul li:nth-child(even) a {
right: 10%;
}
ul li a h1 {
text-align: center;
line-height: 0;
padding-top: 30%;
}
<ul>
<li>
<div>
<div>
<a><h1>1</h1></a>
</div>
</div>
</li>
<li>
<div>
<div>
<a><h1>2</h1></a>
</div>
</div>
</li>
<li>
<div>
<div>
<a><h1>3</h1></a>
</div>
</div>
</li>
<li>
<div>
<div>
<a><h1>4</h1></a>
</div>
</div>
</li>
<li>
<div>
<div>
<a><h1>5</h1></a>
</div>
</div>
</li>
<li>
<div>
<div>
<a><h1>6</h1></a>
</div>
</div>
</li>
</ul>
<div style="clear: both; height: 1000px">
simulating a bunch of height
</div>

Related

Why adding sticky to CSS drop down menu breaks it?

There are many similar examples, but none I found to deal with this issue. I'm trying to make <nav> bar with drop-down menu to be sticky. I have a <nav> bar with many menu entries, but I simplified it as much as possible to see where it breaks. There is simple example from w3schools, modified a bit, and it stops working as soon as I add position:sticky (you can see it commented out bellow)
So example code in one file for practicality is:
<!DOCTYPE html>
<html>
<head>
<style>
body {
font-size: 28px;
}
ul {
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
background-color: #333;
/* position: -webkit-sticky; /* Safari */
/* position: sticky; */ /* If enabled it breaks dropdown menu */
top: 0;
}
li {
float: left;
}
li a, .mDrop {
display: block;
color: white;
text-align: center;
padding: 14px 16px;
text-decoration: none;
}
.mDrop li:nth-of-type(-n+1) { float: down; }
.mDrop {
position: relative;
top: 13.6rem;
}
li .mDrop {
visibility: hidden;
opacity: 0;
width: 8rem;
position: absolute;
transition: all 0.5s ease;
margin-top: 1.5rem;
display: none;
}
li a:hover, .mDrop:hover .li:hover {
background-color: green;
}
li:hover > ul,
li:focus-within > ul,
li ul:hover {
visibility: visible;
opacity: 1;
display: block;
}
ul li ul li { clear: both; width: 100%; }
.active { background-color: #4CAF50; }
</style>
</head>
<body>
<div class="header">
<h2>Scroll Down</h2>
<p>Scroll down to see the sticky effect.</p>
</div>
<ul>
<li><a class="active" href="#home">Home</a></li>
<li>News
<ul class="mDrop">
<li>Drop1</li>
<li>Drop2</li>
<li>Drop3</li>
</ul>
</li>
<li>Contact</li>
<li style="float:right">Help</li>
</ul>
<h3>Sticky Navigation Bar Example</h3>
<p>The navbar will <strong>stick</strong> to the top when you reach its scroll position.</p>
<p>Some text to enable scrolling. </p>
<div style="Height:80vh"></div>
<p>Some text to enable scrolling. </p>
</body>
</html>
I've tried many different options examples and no luck. I don't want to encapsulate entire content area in separate <div>, just would like adding stickiness to working drop-down menu. I also would like solution with CSS/HTML only.
Thanks
Your dropdown is broken because you are giving position: sticky to the ul tag. Since you have two nested uls in your code, the style is applied to both of them.
<ul> <!-- first ul -->
<li><a class="active" href="#home">Home</a></li>
<li>News
<ul class="mDrop"> <!-- second ul -->
...
</ul>
</li>
...
...
</ul>
Solution
First of all, wrap your ul (navbar) in a <nav> element. Don't be afraid of "adding another div". This makes you HTML code more semantic and more readable, no need to say it's good for SEO too.
<nav class="navbar">
<ul>
<li><a class="active" href="#home">Home</a></li>
<li>News
<ul class="mDrop">
<li>Drop1</li>
<li>Drop2</li>
<li>Drop3</li>
</ul>
</li>
<li>Contact</li>
<li style="float:right">Help</li>
</ul>
</nav>
REMOVE these parts from your CSS:
ul {
position: -webkit-sticky; /* remove */
position: sticky; /* remove */
top: 0; /* remove */
}
ADD these to your CSS:
.navbar {
position: sticky;
position: -webkit-sticky;
top: 0;
}
li .mDrop {
visibility: hidden;
opacity: 0;
width: 8rem;
position: absolute;
top: 40px; /* I just added these line. Replace 40px with any value that fits your design */
transition: all 0.5s ease;
margin-top: 1.5rem;
display: none;
}
What I'm basically doing is changing how you "style" your elements. Never use "pure" or "element" selectors like (h1, h2, p, ul) unless you really want to do some general styling; for example, resetting browser default styles.
Full Code
body {
font-size: 28px;
}
.navbar {
position: -webkit-sticky; /* Safari */
position: sticky; /* If enabled it breaks dropdown menu */
top: 0;
}
ul {
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
background-color: #333;
}
li {
float: left;
}
li a,
.mDrop {
display: block;
color: white;
text-align: center;
padding: 14px 16px;
text-decoration: none;
}
.mDrop li:nth-of-type(-n + 1) {
float: down;
}
.mDrop {
position: relative;
top: 13.6rem;
}
li .mDrop {
visibility: hidden;
opacity: 0;
width: 8rem;
position: absolute;
top: 40px;
transition: all 0.5s ease;
margin-top: 1.5rem;
display: none;
}
li a:hover,
.mDrop:hover .li:hover {
background-color: green;
}
li:hover > ul,
li:focus-within > ul,
li ul:hover {
visibility: visible;
opacity: 1;
display: block;
}
ul li ul li {
clear: both;
width: 100%;
}
.active {
background-color: #4caf50;
}
<body>
<div class="header">
<h2>Scroll Down</h2>
<p>Scroll down to see the sticky effect.</p>
</div>
<nav class="navbar">
<ul>
<li><a class="active" href="#home">Home</a></li>
<li>News
<ul class="mDrop">
<li>Drop1</li>
<li>Drop2</li>
<li>Drop3</li>
</ul>
</li>
<li>Contact</li>
<li style="float:right">Help</li>
</ul>
</nav>
<h3>Sticky Navigation Bar Example</h3>
<p>The navbar will <strong>stick</strong> to the top when you reach its scroll position.</p>
<p>Some text to enable scrolling. </p>
<div style="Height:80vh"></div>
<p>Some text to enable scrolling. </p>
</body>

CSS: Position child indepently from parent without using position:absolute

I created a css hover menu with only one level.
HTML
<div id="menu">
<ul>
<li id="item1">item1
<div id="content1"> </div>
</li>
<li id="item2">item2
<div id="content2"> </div>
</li>
<li id="item3">item3
<div id="content3"> </div>
</li>
</ul>
</div>
CSS
html, body {
margin: 0;
height: 100%;
width: 100%;
}
#menu {
width: 0%;
padding-left: 16px;
height: 100%;
background-color: red;
}
#menu:hover {
width: 20%;
}
#content1, #content2, #content3 {
width: 300%;
height: 1000%;
margin-left: 100%;
background-color: green;
visibility: hidden;
left:16px;
}
#item1:hover #content1, #item2:hover #content2, #item3:hover #content3 {
visibility: visible;
}
ul {
list-style: none;
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
#item1, #item2, #item3 {
width: 100%;
height: 10%;
display:none;
}
#menu:hover #item1, #menu:hover #item2, #menu:hover #item3 {
display:block;
}
http://jsfiddle.net/6Bv6C/12/
The menu is hidden at first but will show when you hover over it. The content boxes will show, wenn you hover over the menu items. My problem is: I would like all the content boxes (green background) to show at the same position (top:0 relative to body; left:/width of #menu/) and not relative to their parents (#item1,2,3). All elements should maintain dynamic width and height.
Is this possible with css? If not could I use jquery or js?
Cheers!
I used position:absolute to solve your problem. An absolutely positioned item calculates its' point of reference as the closest parent with the position:relative style. I updated your fiddle with the changes so you can see what I mean: http://jsfiddle.net/6Bv6C/13/

How to prevent from text to extend the <li> container height?

My code - Plunker
I try to create a fluid layout, my sidebar is made of a list of links. I want each <li> element to be a perfect square, the problem starts when I add the text inside. It seems to be adding height to my square and what I get is a rectangle. If you examine my code the dimensions of my list objects are
32px X 43px. How can I prevent from an inside text to extend the <li> elements?
And how can I make the text appear on the bottom left side of the <li> element?
My CSS:
body{
width: 100%;
margin: 0 auto;
}
.content {
width: 95%;
display: inline;
float: left;
}
.sidebar{
width: 5%;
display: inline;
float: left;
}
.sidebar ul{
width: 100%;
margin: 0;
padding: 0;
overflow: hidden;
list-style: none;
}
.sidebar li{
padding: 50%;
background-color: oldlace;
}
.sidebar a{
display: block;
font-size: 0.5em;
}
My HTML:
<body >
<h1>Hello Plunker!</h1>
<div class="sidebar">
<ul>
<li>ANALYTICS</li>
<li>STYLES</li>
<li>VOTERS</li>
<li>GET STARTED</li>
<li>UPDATE</li>
</ul>
</div>
<div class="content">
<p>Blahahhhahhhahahahahahahhahahah blahahahh bluah</p>
</div>
You could use position: relative on the li and position: absolute on the a. Using absolute will cause the a element to not affect the li's dimensions. In this way you can also position it in the corner.
http://plnkr.co/edit/kcjCl1?p=preview
.sidebar li{
padding: 50%;
position: relative;
}
.sidebar a{
display: block;
position: absolute;
bottom: 0;
left: 0;
}

How to center links in header using CSS?

I wanted to make the links centered on the screen rather than placed in a location to a certain number of pixels.
Here's my code:
CSS:
.HorizLinks {
position: absolute;
top: 77px;
left: 180px;
}
.HorizLinks ul {
margin: 0px;
}
.HorizLinks li {
margin: 0px 15px 0px 0px;
list-style-type: none;
display: inline;
}
This is the HTML on the webpage:
<div id="container"></div>
<div id="header"></div>
<div class="HorizLinks">
<ul>
<li>Header Link 1</li>
<li>Header Link 2</li>
</ul>
</div>
Use text-align:center on the <div class="HorizLinks">. Also, set the padding of the ul elements to be 0.
Your absolute positioning of the container div is pushing the whole div to the side itself to the right side of the page, so unless you remove that, the content inside will never be able to be in the middle.
jsFiddle here.
CSS:
.HorizLinks {
text-align:center;
}
.HorizLinks ul {
margin: 0;
padding:0;
}
.HorizLinks li {
margin: 0 15px 0 0;
list-style-type: none;
display: inline;
}

Horizontal Centered Menu in CSS?

I want to make a horizontal centered menu. I have tried using things like text align center and margin auto but can't get them to work. I do not want to use a table.
Here's my code:
<footer class="container">
<div class="row">
<div class="span12">
<ul>
<li>footer info 1</li>
<li>footer info 2</li>
<li>footer info 3</li>
</ul>
</div>
</div>
With the provided HTML:
ul { text-align: center; }
li { display: inline-block; } /* Don't float them */
http://jsfiddle.net/NpLR3/
The following will work without using text-align:
footer {
width: 100%;
}
.row {
position: absolute;
left: 50%;
}
.span12 {
position: relative;
left: -50%;
}
ul {
padding: 0;
}
li {
display: inline;
list-style: none;
margin-left: 1em;
}
li:first-child {
margin-left: 0;
}
The important bits are:
(1) that the outer container for the menu has 100% width,
(2) that the inner container is absolutely positioned at 50% left (which positions the left side of the menu at the center of the page), and
(3) that the menu is then relatively positioned at -50% left (moving it back to the left half its width, so that the center of the menu is now at the center of the page).
The other stuff is just cosmetic.
See working example.
Demo
.container{
background:#ddd;
width: 100%;
text-align:center;
}
li{
display: inline-block;
}
See http://jsfiddle.net/aCSgz/
Basically you need to set the ul and li to display: block.
ul { display: block; text-align:center; }
ul li { display: block; }
You need to set the display property on the LIs to inline-block and set the text-align on the UL to center.
HTML:
<footer class="container">
<div class="row">
<div class="span12">
<ul>
<li>footer info 1</li>
<li>footer info 2</li>
<li>footer info 3</li>
</ul>
</div>
</div>
</footer>
CSS:
footer {
background:#fdd;
}
div.row {
background: #dfd;
}
ul {
background: #ddf;
list-style: none;
margin: 0;
padding: 0;
text-align: center;
}
li {
display: inline-block;
background: #fff;
margin: 0.5em;
padding: 0.5em;
}
http://jsfiddle.net/ghodmode/h2gT3/1/

Resources