Dr. Greg Bernstein
Updated September 12th, 2021
From MDN:
Positioning allows you to take elements out of the normal document layout flow, and make them behave differently, for example sitting on top of one another, or always remaining in the same place inside the browser viewport.
…is the system by which elements are placed inside the browser’s viewport.
Block level elements are laid out vertically in the viewport
Inline elements sit on the same line as one another as long as there is space for them to do so inside the width of the parent block level element.
If there isn’t space, then the overflowing text or elements wil move down to a new line.
If two adjacent elements both have margin set on them and the two margins touch, the larger of the two remains, and the smaller one disappears.
HTML & CSS
<style>.posEx {width:20%; background-color:aliceblue;
border: solid 1px;}
.posEx.reg {background-color: yellow; }
</style>
<p class="posEx">Para 1</p>
<p class="posEx reg">Para 2</p>
<p class="posEx">Para 3</p>
<p class="posEx">Para 4</p>
Para 1
Para 2
Para 3
Para 4
<style>.posEx {width:20%; background-color:aliceblue; border: solid 1px;}
.posEx.rel2 {background-color: yellow; position: relative; top: -20px; left:20px;}
</style>
<p class="posEx">Para 1</p>
<p class="posEx rel2">Para 2</p>
<p class="posEx">Para 3</p>
<p class="posEx">Para 4</p>
Para 1
Para 2
Para 3
Para 4
<div style="position: relative">
<style>.posEx {width:20%; background-color:aliceblue; border: solid 1px;}
.posEx.abs2 {background-color: yellow; position: absolute; top: 20px; left:20%;}
</style>
<p class="posEx">Para 1</p>
<p class="posEx abs2">Para 2</p>
<p class="posEx">Para 3</p>
<p class="posEx">Para 4</p>
</div>
Para 1
Para 2
Para 3
Para 4
<html>
element is the positioning context for an absolutely positioned element.position: relative
to the container element.<div>
in the previous example. This is easy to forget and can cause a lot of debugging time!!!From MDN z-index
The z-index property specifies the z-order of a positioned element and its descendants. When elements overlap, z-order determines which one covers the other. An element with a larger z-index generally covers an element with a lower one.
<div style="position: relative">
<style>p.zEx {width:20%; background-color:aliceblue; border: solid 4px; height: 30vh;}
p.off1 {background-color: yellow; position: absolute; top: 20vh; left:20%;}
p.off2 {background-color: #4ddddf; position: absolute; top: 25vh; left:24%;}
p.off3 {background-color: #e0aefd; position: absolute; top: 30vh; left:28%;}
p.off4 {background-color: #fc8bb1; position: absolute; top: 35vh; left:32%;}
</style>
<p class="zEx off1">Para 1</p>
<p class="zEx off2">Para 2</p>
<p class="zEx off3">Para 3</p>
<p class="zEx off4">Para 4</p>
</div>
Para 1
Para 2
Para 3
Para 4
Set z-index higher on third paragraph.
<div style="position: relative">
<style>
p.raiseZ {z-index: 5}
</style>
<p class="zEx off1">Para 1</p>
<p class="zEx off2">Para 2</p>
<p class="zEx off3 raiseZ">Para 3</p>
<p class="zEx off4">Para 4</p>
</div>
Para 1
Para 2
Para 3
Para 4
Set z-index higher on 2nd paragraph.
<div style="position: relative">
<style>
p.raiseZ {z-index: 5}
</style>
<p class="zEx off1">Para 1</p>
<p class="zEx off2 raiseZ">Para 2</p>
<p class="zEx off3">Para 3</p>
<p class="zEx off4">Para 4</p>
</div>
Para 1
Para 2
Para 3
Para 4
From MDN:
…fixed positioning fixes an element in place relative to the browser viewport itself. This means that you can create useful UI items that are fixed in place, like persisting navigation menus.
<header>
element.<!DOCTYPE html>
<html lang="en">
<head>
<title>Fixed Positioning Example</title>
</head>
<body>
<header>
<p>Our Heading/Branding Area!</p>
<div class="controls">
<input id="Static" type="radio" name="PosIt" checked value="Static">
<label for="Static">static</label>
<input id="Fixed" type="radio" name="PosIt" value="Fixed">
<label for="Fixed">fixed</label>
</div>
</header>
<section class="Blabber">
<p> Leverage agile frameworks to ...</p>
<p> Bring to the table win-win survival...</p>
<p> Capitalize on low hanging fruit... </p>
<p>Podcasting operational change ...</p>
<p>Collaboratively administrate ...</p>
</section>
</body>
</html>
var header;
var blabber;
function radioHandler(event) {
// Toggling two classes on/off at the same time!
header.classList.toggle("FixedHead");
blabber.classList.toggle("AdjustBlabber");
}
window.onload = function() {
header = document.querySelector("header");
blabber = document.querySelector(".Blabber");
let radios = document.querySelectorAll("[type='radio']");
for (let radio of radios) { // Is there a better way?
radio.addEventListener('change', radioHandler);
}
}
.FixedHead {
position: fixed;
top: 0px;
left: 0px;
}
.AdjustBlabber { /* Fixed doesn't reserve space! */
margin-top: 98px;
}
body {margin: 0;}
header {
background-color: cadetblue;
color: white;
width: 100%;
}
header p,
header>div {
display: inline-block;
font-family: sans-serif;
padding: 1em;
}
header p {
border-right: 2px solid;
}
section.Blabber {
width: 200px;
margin-left: auto;
margin-right: auto;
}
display
property (none, block)relative
position to establish contextabsolute
position for “drop down” (or “pop up”)Hello World!
Hello Web Dev!
<div id="DropEx">
<div class="dropdown">
<span>Mouse over me</span>
<div class="dropdown-content">
<p>Hello World!</p>
</div>
</div>
<div class="dropdown">
<span>Another</span>
<div class="dropdown-content">
<p>Hello Web Dev!</p>
</div>
</div>
</div>
<div id="DropEx">
: Used to isolate the styling of this example from the slide styling.<div class="dropdown">
: Used for setting up individual drop downs and as a hover target.<div class="dropdown-content">
: Used to hold the content of the “drop down” (or “pop up”)Why do we need relative? Why do we need inline-block?
#DropEx .dropdown {
position: relative;
display: inline-block;
}
#DropEx span {
display: inline-block;
background-color:beige;
width: 10em;
}
Use of absolute positioning. Use of display property.
#DropEx .dropdown-content {
display: none;
position: absolute;
left: 10px; /* sets from container left */
top: 30px; /* sets from container top */
background-color: aliceblue;
padding: 0.5em;
border: solid blue 10px;
min-width: 10em;
z-index: 1;
}
#DropEx .dropdown:hover .dropdown-content {
display: block;
}
A hybrid approach between MDN and BootStrap
<section class="tabbed-panes">
<ul class="tabbed-controls">
<li><a href="#Foil" class="active">Foil</a></li>
<li><a href="#Slalom">Slalom</a></li>
<li><a href="#Wave">Wave</a></li>
</ul>
<div class="panes">
<article id="Foil" class="active-pane">
<h2>The Joy of Foiling</h2>
<p>Blah...e</p>
</article>
<article id="Slalom">
<h2>The Speed of Slalom</h2>
<p>Stuff...</p>
</article>
<article id="Wave">
<h2>The Challenge of Waves</h2>
<p>More stuff...</p>
</article>
</div>
</section>
section.tabbed-panes
ul.tabbed-controls
div.panes
.panes article
.active-pane { /* brings to front */
z-index: 1;
}
* {
box-sizing: border-box;
}
section.tabbed-panes {
height: 12em; /* Overall widget height */
border: dashed red 2px;
}
div.panes {
position: relative; /* Establish context! */
}
div.panes>article {
height: 8em; /* Fit inside containers space */
overflow: auto;
position: absolute;
background-color: white; /* Opaque, stuff underneath doesn't show */
border: lightgray solid 2px;
padding-left: 0.3em;
width: 100%; /* take full width even if shorter */
top: 0;
left: 0;
}
.tabbed-controls li {
width: 10%;
display: inline-block;
list-style: none;
}
<a>
in the .tabbed-controls
active-pane
class to appropriate <article>
s to adjust z-indextabbed-panes
section in the document. (BootStrap can, MDN cannot)function tabClick(event) {
event.preventDefault();
let target = event.target;
let href = target.getAttribute("href");
console.log("Tabbed clicked: " + target);
console.log("Href: " + href);
let tabSection = target.parentElement.parentElement.parentElement;
console.log(tabSection);
// Remove the active-pane class from all panes within
// this tabSection
let panes = tabSection.querySelectorAll('.panes article');
panes.forEach(function(p) {
p.classList.remove("active-pane");
});
let activePane = tabSection.querySelector(href);
activePane.classList.add("active-pane");
}
window.onload = function() {
let tabControls = document.querySelectorAll(".tabbed-controls>li");
tabControls.forEach(function(tc){
tc.addEventListener("click", tabClick);
});
}