Two Fixed Width Full Height Columns, with Seamless Transition to Blank Space

Two fixed width full height columns, with seamless transition to blank space

See: http://jsbin.com/amunuz

<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>JS Bin</title>
<style>
html, body {
height: 100%;
}
body {
margin: 0;
background: -moz-linear-gradient(left, #ff0000 50%, #00a9ff 50%);
background: -webkit-gradient(linear, left top, right top, color-stop(50%,#ff0000), color-stop(50%,#00a9ff));
background: -webkit-linear-gradient(left, #ff0000 50%,#00a9ff 50%);
background: -o-linear-gradient(left, #ff0000 50%,#00a9ff 50%);
background: -ms-linear-gradient(left, #ff0000 50%,#00a9ff 50%);
background: linear-gradient(left, #ff0000 50%,#00a9ff 50%);
}
#container {
height: 100%;
display: table;
table-layout: fixed;
width: 960px;
margin: 0 auto;
}
#navigation {
display: table-cell;
width: 200px;
background: #ff0000;
}
#content {
display: table-cell;
background: #00a9ff;
}
</style>
</head>
<body>
<div id="container">
<div id="navigation">navigation</div>
<div id="content">content</div>
</div>
</body>
</html>

Tricky CSS situation with centered page and two separate backgrounds on the left and right

I've managed to get this done using CSS and JS (using jquery, but you could do similar stuff using pure JS). I set the left/right to simply use different background colours - feel free to use images.

CSS:

body {
margin: 0px;
}

#full {
min-width: 960px;
position: relative;
}

#dleft {
min-width: 319px;
background-color: darkGray;
border-right: solid 3px gray;
height: 200px;
position: absolute;
top: 0px;
left: 0px
}

#dright {
min-width: 638px;
background-color: lightGray;
height: 200px;
position: absolute;
top: 0px;
right: 0px;
}

.left-content {
float: right;
border-top: solid 1px gray;
border-bottom: solid 1px gray;
width: 299px;
padding: 10px;
margin-top: 10px;
}

.right-content {
float: left;
border-top: solid 1px gray;
border-bottom: solid 1px gray;
width: 618px;
padding: 10px;
margin-top: 10px;
}

JS:

function resizeDivs()
{
var WIDM = 960;
var WIDL = 319;
var WIDR = 638;

var ww = $(window).width();

if(ww <= WIDM)
{
$('#full').width(WIDM);
$('#dleft').width(WIDL);
$('#dright').width(WIDR);
}
else
{
var pad = (ww - WIDM) / 2;
$('#full').width(ww);
$('#dleft').width(WIDL + pad);
$('#dright').width(WIDR + pad);
}
}

$(document).ready(resizeDivs);
$(window).resize(resizeDivs);

And, finally, HTML:

<body>
<div id="full">
<div id='dleft'>
<div class="left-content">
Left Column
</div>
</div>
<div id='dright'>
<div class="right-content">
Right Column
</div>
</div>
</div>
</body>

css width transition gives parent full width before animation begins

You're already using CSS variables for changing width and implementing animations.

See the example below for using them in the correct way in order to achieve the animation you wanted.

const input = document.querySelector("input");

setInterval(() => {
input.parentElement.classList.toggle("expanded");
input.classList.toggle("expanded");
}, 1000);
@import "https://cdn.jsdelivr.net/gh/KunalTanwar/normalize/css/normalize.inter.min.css";

body {
height: 100%;
display: grid;
place-items: center;
background-color: #131417;
}

.container {
--base: 16px;
--btn-size: 56px;
--duration: 500ms;
--max-width: calc(var(--btn-size));
width: 100%;
display: flex;
overflow: hidden;
box-shadow: 0 0 0 1px red;
max-width: var(--max-width);
transition: max-width var(--duration);
}
.container.expanded {
--max-width: calc(var(--base) * 30);
}
.container button {
border: 0;
aspect-ratio: 1/1;
width: var(--btn-size);
height: var(--btn-size);
background-color: #373c49;
}
.container input {
width: 0%;
border: 0;
color: white;
padding: var(--base);
background-color: black;
transition: width var(--duration);
}
.container input.expanded {
width: 100%;
}
<div class="container">
<button type="button"></button>
<input type="text" placeholder="Search" />
</div>

fixed width variable height grid css

The easiest option is to use the jQuery Masonry plugin.

If you want to do it via CSS only, you have to float large, equal width columns and then add your variable height elements within them.

<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
<div class="parent">
<div class="child"></div>
<div class="child"></div>
</div>

And the CSS would look like so:

.parent {
float: left;
width: 200px; /* adjust as needed */
}

.child {
/* these are variable height */
}

Unsmooth sliding-up animation

The problem

Your #panel is a sibling of main, but you want #panel to be fixed on the upper side of the viewport even when scrolling: You solved that with position: fixed.

But using position: fixed means that #panel will only be perfectly layed out on certain screen sizes. On any other screen size, and it may overlap main's content. Also, it may cause visual jitter when animating (see section "Using position: sticky").

You also want #panel to slide out when requested, and main to take up the then-empty space: You solved that slide-out and "slide into place" with 2 different animations; #panel moves out by a lot, but main moves only enough to take up the empty space. Additionally, they move for a different duration.

The different distances and durations of the animations cause them to be not in sync with each other. Ideally both should move by the same amount and in the same time to make it look smooth.

Overexaggerated example of the issue:

section:hover #banner {
top: -400px;
transition-duration: 1s;
}
section:hover #content {
top: -80px;
transition-duration: 2s;
}

/* PRESENTATIONAL STYLING */
body {font-family:sans-serif}
section {
width: fit-content;
display: grid;
grid-template-columns: repeat(2, 1fr);
}

#viewport {
border: 1px solid black;
grid-row: 1/1;
grid-column: 1/-1;
}
#page {
grid-row: 1/1;
grid-column: 2/2;
}

#banner, #content {
z-index: -1;
--size: 80px;
position: relative;
top: 0;
width: var(--size);
height: var(--size);
color: white;
transition-property: top;
}
#banner {background-color:firebrick}
#content {background-color:darkblue}
<section>
<div id="viewport">Viewport</div>
<div id="page">
<div id="banner">Banner</div>
<div id="content">Content</div>
</div>
</section>


Related Topics



Leave a reply



Submit