HTML / CSS two layered layout separately scrollable - html

Hi team,
I am looking to build such a layout, but I struggle with finding be correct way to do it. I have played around with two divs with position = absolute, but it does not work with all my requirements. Any suggestion on how to get the top-nav in as well as a fixed sub-nav on the right panel?
html {
width: 100%;
height: 100%;
}
#leftCol {
background: #ddd;
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 80%;
overflow: auto;
padding: 2em;
font-size: 16px;
}
#rightCol {
background: #bbb;
position: absolute;
left: 20%;
top: 0;
bottom: 0;
right: 0;
overflow-y: auto;
padding: 2em;
font-size: 66px;
}
<body style="padding: 0; margin: 0;">
<div>test</div>
<div id="leftCol">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque eu ligula turpis, in euismod velit. Sed suscipit commodo nisl ac tempor. Donec eu nulla eros. Donec tortor justo, eleifend eu consectetur at, fermentum a semidunt rhoncus auctor.</p>
</div>
<div id="rightCol">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque eu ligula turpis, in euismod velit. Sed suscipit commodo nisl ac tempor. Donec eu nulla eros. Donec tortor justo, eleifend eu consectetur at, fermentum a sem. Vestibulum tempus velit
vel neque rutrum congue. Donec vehicula dictum mi, sit amet suscipit augue rhoncus vitae. Curabitur tempus auctor bibendum. Sed sodales iaculis egestas. Suspendisse consectetur elementum ligula et imperdiet. Proin in velit eu arcu dapibus faucibus.
Vivamus fringilla adipiscing mauris ac condimentum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse ut nibh ac nulla tempus malesuada. Ut congue, arcu quis semper pellentesque, nunc quam
volutpat libero, a rhoncus metus sem eu dolor. Vestibulum lacinia augue sit amet nibh imperdiet eu volutpat nibh egestas. Suspendisse luctus laoreet mattis. Proin in euismod augue. Duis tincidunt rhoncus auctor.</p>
</div>
</body>
Thank you!
fj

I'm a fan of grid-template-areas for this. See below:
body {
margin:0;
height: 100vh;
display: grid;
grid-template-areas:
"nav nav"
"sidebar subnav"
"sidebar main"
;
grid-template-rows: fit-content(2rem) fit-content(2rem) 1fr;
grid-template-columns: 10rem 1fr;
}
nav {
background-color: #4472C4;
grid-area: nav;
display: flex;
}
nav .spacer {
flex-grow:2;
}
.nav-item, .subnav-item {
padding: 0.5rem 0.25rem;
}
aside {
position: relative;
background-color: #ED7D31;
grid-area: sidebar;
padding: 0.25rem;
}
.aside-scrollable {
position: absolute;
inset: 0;
overflow-y:auto;
}
.subnav {
background-color: #00B050;
grid-area: subnav;
display: flex;
}
main {
background-color: #A9D18E;
grid-area: main;
height: 100%;
overflow-y: scroll;
}
<nav>
<div class='nav-item'>Left-side icon (fixed)</div>
<div class='spacer'></div>
<div class='nav-item'>Item 1</div>
<div class='nav-item'>Item 2</div>
<div class='nav-item'>Item 3</div>
</nav>
<aside>
<div class='aside-scrollable'>
Left side scrollable
</div>
</aside>
<div class='subnav'>
<div class='subnav-item'>Item 1</div>
<div class='subnav-item'>Item 2</div>
<div class='subnav-item'>Item 3</div>
<div class='subnav-item'>Item 4</div>
<div class='subnav-item'>Item 5</div>
</div>
<main>
Some content here
</main>

I would use flex for your main layout and then absolutely positioned elements for your scroll areas:
Basic Layout
html,
body {
height: 100%;
}
body {
display: flex;
flex-direction: column;
margin: 0;
}
header {
background: blue;
}
main {
flex-grow: 1;
display: flex;
}
nav {
width: 200px;
background: orange;
}
.content {
flex-grow: 1;
display: flex;
flex-direction: column;
}
.content-header {
background: green;
}
.content-body {
flex-grow: 1;
background: lightgreen;
}
.scroll-container {
position: relative;
}
.scroll {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
overflow: auto;
}
<header>header</header>
<main>
<nav class="scroll-container">
<div class="scroll">nav</div>
</nav>
<div class="content">
<div class="content-header">content header</div>
<div class="content-body scroll-container">
<div class="scroll">content body</div>
</div>
</div>
</main>
With enough content to scroll
html,
body {
height: 100%;
}
body {
display: flex;
flex-direction: column;
margin: 0;
}
header {
background: blue;
}
main {
flex-grow: 1;
display: flex;
}
nav {
width: 200px;
background: orange;
}
.content {
flex-grow: 1;
display: flex;
flex-direction: column;
}
.content-header {
background: green;
}
.content-body {
flex-grow: 1;
background: lightgreen;
}
.scroll-container {
position: relative;
}
.scroll {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
overflow: auto;
}
/* this is just to create height so it makes the container overflow */
.scroll-block {
height: 1000px;
}
<header>header</header>
<main>
<nav class="scroll-container">
<div class="scroll">
nav
<div class="scroll-block"></div>
nav bottom
</div>
</nav>
<div class="content">
<div class="content-header">content header</div>
<div class="content-body scroll-container">
<div class="scroll">
content body
<div class="scroll-block"></div>
content body bottom
</div>
</div>
</div>
</main>

You'd need a fixed height on the scrollable items and you need your vertical overflow set to scroll.
That's how I did it anyway:
.createForm form {
height: 80vh !important;
overflow-y: scroll !important;
overflow-x: hidden !important;
margin-bottom: 50px;
}
Hope this helps!

Related

HTML Body is overflown

I'm trying to create a website where the first part is a video, on top of it is a navigation bar and description sentence. The second part is a div with a picture and a lorem ipsum paragraph. But the two-part is mushed together. Do you know why?
The first part is the video-container div. It contains a video, a navigation bar and some introductory words
The second part is the intro div which has an image and a paragraph side by side
<style>
html,
body {
border: 1px solid blue;
min-height:100%;
padding:0;
margin:0;}
* {
font-family: 'Playfair Display', serif;
margin: 0;
padding: 0;
border: 0;
outline: 0;
margin-top: -5px;
}
.nav {
border: 1px solid red;
margin-right: 30px;
display: flex;
align-items: center;
justify-content: space-between;
}
.nav li {
list-style-type: none;
}
.nav li a {
text-decoration: none;
font-size: 23px;
font-weight: 600;
color: #C71585;
letter-spacing: 0.03em;
}
.nav img {
width: 150px;
}
video {
width: 100%;
position: absolute;
object-fit: cover;
background-size: cover;
top: 0px;
left: 0px;
min-width: 100%;
min-height: 100%;
z-index: -1;
box-sizing: content-box;
}
.video-container {
position: relative;
height: 100%;
border: 1px solid yellow;
}
.content {
border: 1px solid yellow;
position: absolute;
left: 50px;
top: 150px;
margin: 10px;
padding: 5px 20px;
font-size: 20px;
overflow: none;
}
.content h1 {
font-size: 100px;
color: #C71585;
}
#myBtn {
margin-left: 20px;
margin-top: 40px;
border: 1px solid #C71585;
font-size: 26px;
font-weight: 800;
color: #e827a0;
padding: 15px 60px;
background-color: transparent;
transition: 0.2s ease-in;
}
#myBtn:hover {
background-color: rgba(199, 21, 133);
color: white;
}
.intro {
overflow: none;
margin-top: 30px;
display: flex;
justify-content: space-around;
align-items: center;
}
.intro img {
width: 500px;
}
.intro-text {
width: 30%;
}
</style>
</head>
<body>
<div class="video-container">
<video autoplay muted loop id="video">
<source src="video.mp4" type="video/mp4">
</video>
<div class="nav">
<img src="logo.png" alt="logo">
<li>About me</li>
<li>My Portfolio</li>
<li>My resume</li>
<li>Contact me</li>
</div>
<div class="content">
<h1>Avid learner and</h1>
<h1>Constant striver</h1>
<button id="myBtn">Who am I</button>
</div>
</div>
<div class='intro'>
<img src="01.jpeg" alt="">
<div class="intro-text">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. In pellentesque ex a felis laoreet, ut bibendum sem eleifend. Quisque egestas sem sed velit molestie tincidunt. Phasellus at pellentesque odio. Phasellus sem leo, hendrerit et massa vehicula, iaculis cursus erat. Vestibulum et viverra nisi, sit amet condimentum sem. Duis gravida faucibus nisl nec pharetra. Curabitur convallis risus enim, nec semper lorem cursus varius. Quisque feugiat vitae dui non ultricies. Integer ipsum quam, dictum et quam nec, imperdiet euismod nulla. Nam bibendum sagittis orci, eget tincidunt risus luctus nec. Quisque lacus urna, tincidunt vel lobortis in, suscipit sit amet nunc. Fusce ultrices erat a nunc dignissim hendrerit. Maecenas sed pharetra quam, vitae suscipit nunc. Aenean molestie dui aliquet augue eleifend, quis congue ligula laoreet. Ut quis est pellentesque, fringilla odio ac, tincidunt nibh.
</div>
</div>
</body>
You can make use of css flex property, in your case please add
.flex-container {
display: flex;
flex-wrap: wrap;
}
under your style tags and assign this class to intro class div as <div class='intro flex-container'>, will this worked for you?
you can easily wrap the .video-container and .intro divs with a div tag and give it style display flex and make sure you add flex wrap also.
Then just give your video and intro containers width 100%

Use only max-height to adjust to content height

I have a modal centered horizontally and vertically where body content scrolls when its big.
However when the body content is less than modal height the modal does not resize down to its content.
I tried to use only max-height an not height but then my modal code breaks ...
Note: Run the code in full page to see the blank space under body content
.cover {
background-color: rgba(0, 0, 0, 0.4);
bottom: 0;
height: 100%;
left: 0;
padding: 0;
position: fixed;
right: 0;
top: 0;
width: 100%;
z-index: 200;
}
.modal {
background-color: white;
margin: 10% auto;
max-width: 400px;
height: 60vh;
max-height: 60vh;
position: relative !important;
}
.scrollView {
position: relative;
border: 2px solid red;
height: calc(60vh - 100px);
margin: 50px 0;
top: 50px;
overflow: scroll;
z-index: 800;
}
div.header {
display: flex;
align-items: center;
height: 50px;
max-height: 50px;
top: 0;
position: absolute;
background: lightgreen;
width: 100%;
z-index: 900;
justify-content: space-between;
}
.header div {
padding: 0 20px;
}
div.footer {
display: flex;
justify-content: center;
align-items: center;
position: absolute;
bottom: 0;
height: 50px;
background: orange;
width: 100%;
}
.body {
overflow-y: scroll;
}
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi porttitor aliquet orci sit amet fringilla. Duis a ligula consequat, ornare elit eu, tincidunt turpis.
</p>
<p>Nulla faucibus ultrices est eu laoreet. Suspendisse accumsan blandit ipsum ultricies congue. Nam eget leo a elit vestibulum tincidunt in elementum nunc. Nunc cursus lacus eu placerat auctor.
</p>
<div class="cover">
<div class="modal">
<div class="header">
<div>Header</div>
<div>Close</div>
</div>
<div class="scrollView">
<div class="body">
Body short content
</div>
</div>
<div class="footer">
Footer
</div>
</div>
</div>
How can I solve this?
You can simplify your code like below and rely on flexbox inside the modal instead of position:absolute;
.cover {
background-color: rgba(0, 0, 0, 0.4);
bottom: 0;
left: 0;
position: fixed;
right: 0;
top: 0;
z-index: 200;
display:flex;
align-items:center;
justify-content:center;
}
.modal {
background-color: white;
max-width: 400px;
width:100%;
max-height: 60vh;
display:flex;
flex-direction:column;
}
.scrollView {
flex-grow:1;
border: 2px solid red;
overflow: auto;
}
div.header,
div.footer{
display: flex;
align-items: center;
justify-content: space-between;
height: 50px;
background: lightgreen;
padding: 0 20px;
flex-shrink:0;
}
div.footer {
background: orange;
justify-content: center;
}
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi porttitor aliquet orci sit amet fringilla. Duis a ligula consequat, ornare elit eu, tincidunt turpis.
</p>
<p>Nulla faucibus ultrices est eu laoreet. Suspendisse accumsan blandit ipsum ultricies congue. Nam eget leo a elit vestibulum tincidunt in elementum nunc. Nunc cursus lacus eu placerat auctor.
</p>
<div class="cover">
<div class="modal">
<div class="header">
<div>Header</div>
<div>Close</div>
</div>
<div class="scrollView">
<div class="body">
Body <br>short <br>content
</div>
</div>
<div class="footer">
Footer
</div>
</div>
</div>

CSS not being applied on Angular application

I have a Modal service which HTML/CSS is working fine (StackBlitz Angular Static HTML)
div.cover {
align-items: center;
background-color: rgba(0, 0, 0, 0.4);
bottom: 0;
display: flex;
justify-content: center;
left: 0;
position: fixed;
right: 0;
top: 0;
z-index: 200;
}
div.modal {
background-color: white;
display: flex;
flex-direction: column;
max-height: 60vh;
max-width: 400px;
width: 100%;
}
div.head {
align-items: center;
background-color: white;
border-bottom: 1px solid gray;
display: flex;
flex-shrink: 0;
height: 50px;
justify-content: space-between;
padding: 0 20px;
}
div.body {
background-color: white;
flex-grow: 1;
overflow: auto;
}
div.view {
padding: 20px 28px;
}
div.foot {
align-items: center;
background-color: white;
border-top: 1px solid gray;
display: flex;
flex-shrink: 0;
height: 50px;
justify-content: flex-end;
padding: 0 20px;
}
p {
margin: 0;
padding: 0;
}
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi porttitor aliquet orci sit amet fringilla. Duis a ligula consequat, ornare elit eu, tincidunt turpis.
</p>
<p>Nulla faucibus ultrices est eu laoreet. Suspendisse accumsan blandit ipsum ultricies congue. Nam eget leo a elit vestibulum tincidunt in elementum nunc. Nunc cursus lacus eu placerat auctor.
</p>
<div class="cover">
<div class="modal">
<div class="head">
<div>Head</div>
<div>Close</div>
</div>
<div class="body">
<div class="view">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi porttitor aliquet orci sit amet fringilla. Duis a ligula consequat, ornare elit eu, tincidunt turpis.
</p>
<p>
Nulla faucibus ultrices est eu laoreet. Suspendisse accumsan blandit ipsum ultricies congue. Nam eget leo a elit vestibulum tincidunt in elementum nunc. Nunc cursus lacus eu placerat auctor.
</p>
</div>
</div>
<div class="foot">
Foot
</div>
</div>
</div>
I then used a Modal.Service to open the content StackBlitz Angular Modal Service
When "Open Modal" is clicked the Modal shows and it looks as expected.
However when the browser window is resized in its height the modal does not resize.
Any idea what might be wrong?
The flex is incomplete, you need to define more to get expected behavior when it hits the max-height parameter. For example, if you want it to shrink and scroll when the content overflows with the vh shrinking try:
div.modal {
background-color: white;
display: flex;
flex-direction: column;
max-height: 60vh;
max-width: 400px;
width: 100%;
flex-shrink: 1;
overflow-y: auto;
}
Defining the flex-shrink is really the big part there though.
https://stackblitz.com/edit/modal-angular-flex-2-rysjej
A couple of mistakes. And angular encompasses your HTML around the component selector element. In this case your modal content was inside <content> which doesn't have flex applied.
div.cover {
flex-direction: column;
}
div.modal {
flex-grow: 1;
}
div.modal > content {
display: flex;
flex-direction: column;
height: 100%;
}

Expand div automatically when floated sibling is hidden

Is it possibly to automatically expand a div to maximum width once it's floated sibling style set to display:none?
Please take a look at this example:
It's easy with flexbox - children expand by default:
document.querySelector("button").addEventListener("click", function() {
document.querySelector(".b").classList.toggle("hidden");
});
body {
display: flex; /* this is the important bit */
}
div {
border: 0.1em solid black;
margin: 0.5em;
padding: 0.5em;
}
.b {
width: 15%;
flex-shrink: 0;
}
.hidden {
display: none;
}
<div class="a">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean eu felis at metus convallis ornare. Pellentesque in porttitor elit. Sed augue augue, vulputate in laoreet quis, vehicula et arcu. Nullam feugiat elit purus, id euismod ligula sodales nec. Vestibulum mattis molestie lacus. <button>Toggle B</button>
</div>
<div class="b"></div>
Browser support is really good for some time now: https://caniuse.com/#feat=flexbox
Another option would be display: table:
document.querySelector("button").addEventListener("click", function() {
document.querySelector(".b").classList.toggle("hidden");
});
body {
display: table;
border-spacing: 1em;
border-collapse: separate;
}
.a, .b {
border: 0.1em solid black;
padding: 0.5em;
display: table-cell;
height: 5em;
}
.a {
width: 85%;
}
.b {
width: 15%;
}
.hidden {
display: none;
}
<div class="a">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean eu felis at metus convallis ornare. Pellentesque in porttitor elit. Sed augue augue, vulputate in laoreet quis, vehicula et arcu. Nullam feugiat elit purus, id euismod ligula sodales nec.
Vestibulum mattis molestie lacus. <button>Toggle B</button>
</div>
<div class="b"></div>
But… it feels kinda hacky to me. Just use flexbox if you don't need support for ancient browsers.
This is how I'd do it. See if it works for you.
document.querySelector("button").addEventListener("click", function(){
document.querySelector(".a").classList.toggle("hidden");
});
body{
display: block;
}
.container{
width: 96%;
margin-left: 2%;
}
.a, .b {
float: right;
height: 5em;
}
.a {
width: 15%;
background: #00E676;
}
.b {
width: 85%;
background: #1E88E5;
font-family: Calibri;
line-height: 2em;
}
.hidden {
display: none;
}
.hidden ~ .b{
width: 100%;
}
button{
margin: 100px 100px;
}
<div class="container">
<div class="a"></div>
<div class="b"></div>
</div>
<button>Toggle</button>

Split div with diagonal line

How would you split a div into 2 parts (both containing horizontal text) by a diagonal line?
e.g. see this where 1 has a rectangular background image and 2 has text with a background color:
You can do it with a pseudo element rotated like this:
body {
background-color: #00bcd4;
}
.main {
margin: 50px;
overflow: hidden;
position: relative;
width: 350px;
}
.image {
background: url(https://s-media-cache-ak0.pinimg.com/564x/ca/9b/ca/ca9bca4db9afb09158b76641ea09ddb6.jpg) center center no-repeat;
background-size: cover;
height: 200px;
}
.text {
background-color: white;
padding: 30px;
position: relative;
}
.text > div {
position: relative;
z-index: 1;
}
.text:before {
content: "";
background-color: white;
position: absolute;
height: 100%;
width: 120%;
top: -20px;
left: -10%;
transform: rotate(5deg);
z-index: 0;
}
<div class="main">
<div class="image"></div>
<div class="text">
<div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent vitae gravida purus. Ut quis elit magna. Fusce et mattis sapien. Sed venenatis magna ut ligula facilisis, eget vulputate neque aliquet. Nulla lacinia condimentum leo non aliquet. Integer
et enim dapibus, tempor ipsum non, fringilla enim. Cras semper fermentum dolor, at pharetra dolor ornare sit amet. Morbi eu dictum orci, tincidunt pretium nisi. Sed finibus vulputate eleifend. Nulla ac leo facilisis, fermentum tellus in, feugiat
risus. Curabitur in sem luctus, pellentesque justo nec, aliquet velit. Nam euismod est sit amet ultrices consequat.
</div>
</div>
</div>
As per my knowledge, its cannot be done using any single CSS property directly, you will have to hack it via using pseudo-elements, or best approach will be do it using SVG
.container {
width: 90%;
margin: 0 auto;
}
.box {
width: 200px;
height: 150px;
text-align: center;
}
.box-1 {
background: #ff6347;
}
.box-2 {
background: #0ff;
}
.box-2:before {
display: inline-block;
margin: 0;
margin-top: -30px;
margin-left: -30px;
content: '';
border: 30px solid transparent;
border-right: 200px solid #0ff;
}
<div class="container">
<div class="box box-1"></div>
<div class="box box-2">
TITLE 1
</div>
</div>
.container {
width: 400px;
margin: 0 auto;
}
.box {
width: 200px;
height: 150px;
text-align: center;
float: left;
}
.box-1 {
background: #ff4500;
}
.box-2 {
background: #0ffab9;
}
.box-2:before {
display: inline-block;
margin: 0;
margin-left: -101px;
margin-top: -1px;
position: absolute;
content: '';
width: 0;
height: 0;
border-bottom: 151px solid #0ffab9;
border-left: 30px solid transparent;
}
<div class="container">
<div class="box box-1">
</div>
<div class="box box-2">
TITLE 1
</div>
</div>