How to make some CSS Grid elements stick to the viewport? - css

I'm try to have 100vh viewport with multiple responsive overlay on top of that
Here is the code, I can make header element get fixed on the viewport with position sticky but for the rest that doesn't work
Also, I'm trying to use CSS Grid for this
Here is the code
body {
display: grid;
grid-template-columns: 1fr minmax(20em, 30vw);
grid-template-rows: clamp(3em, 10vh, 5em) 1fr clamp(7em, 20vh, 9em);
}
header {
background-color: #eee;
grid-column: 1 / end;
grid-row: 1 / 2;
}
main {
height: 100vh;
grid-column: 1 / end;
grid-row: 1 / end;
}
aside {
background-color: #ccc;
grid-column: 2 / end;
grid-row: 2 / end;
}
footer {
background-color: #444;
grid-row: 3 / end;
grid-column: 1 / end;
}
<body>
<header></header>
<main>
<section class="questions" id="objectives">
<h2>Objectives</h2>
<div class="question">
<h3>1. Lorem ipsum dolor sit amet, consectetur adipisicing.</h3>
<button>Yes</button><button>No</button>
</div>
<div class="question">
<h3>2. Lorem ipsum dolor sit amet, consectetur adipisicing.</h3>
<button>Yes</button><button>No</button>
</div>
<div class="question">
<h3>3. Lorem ipsum dolor sit amet, consectetur adipisicing.</h3>
<button>Yes</button><button>No</button>
</div>
<div class="question">
<h3>4. Lorem ipsum dolor sit amet, consectetur adipisicing.</h3>
<button>Yes</button><button>No</button>
</div>
<div class="question">
<h3>5. Lorem ipsum dolor sit amet, consectetur adipisicing.</h3>
<button>Yes</button><button>No</button>
</div>
<div class="question">
<h3>6. Lorem ipsum dolor sit amet, consectetur adipisicing.</h3>
<button>Yes</button><button>No</button>
</div>
<div class="question">
<h3>7. Lorem ipsum dolor sit amet, consectetur adipisicing.</h3>
<button>Yes</button><button>No</button>
</div>
<div class="question">
<h3>8. Lorem ipsum dolor sit amet, consectetur adipisicing.</h3>
<button>Yes</button><button>No</button>
</div>
<div class="question">
<h3>9. Lorem ipsum dolor sit amet, consectetur adipisicing.</h3>
<button>Yes</button><button>No</button>
</div>
</section>
</main>
<aside></aside>
<footer></footer>
</body>
Codepen https://codepen.io/ikamy/pen/rNYwOwM
Please vertically minimize and then scroll
I'm trying to fix footer and aside without using position fixed or absolute
While the body is display Grid I'm trying to use with: 100vh on the body and make the other Grid elements sticks , and I only scroll on the main element

You need to use min-height:100vh instead of height:100vh
And then use position:sticky on element you want to be sticky with top or bottom.
body {
display: grid;
grid-template-columns: 1fr minmax(20em, 30vw);
grid-template-rows: clamp(3em, 10vh, 5em) 1fr clamp(7em, 20vh, 9em);
}
header {
background-color: #eee;
grid-column: 1 / end;
grid-row: 1 / 2;
}
main {
min-height:100vh;
grid-column: 1 / end;
grid-row: 1 / end;
}
aside {
background-color: #ccc;
grid-column: 2 / end;
grid-row: 2 / end;
position: sticky;
top: 0;
z-index:99999;
}
footer {
background-color: #444;
grid-row: 3 / end;
grid-column: 1 / end;
position: sticky;
bottom: 0
;
}
<body>
<header></header>
<main>
<section class="questions" id="objectives">
<h2>Objectives</h2>
<div class="question">
<h3>1. Lorem ipsum dolor sit amet, consectetur adipisicing.</h3>
<button>Yes</button><button>No</button>
</div>
<div class="question">
<h3>2. Lorem ipsum dolor sit amet, consectetur adipisicing.</h3>
<button>Yes</button><button>No</button>
</div>
<div class="question">
<h3>3. Lorem ipsum dolor sit amet, consectetur adipisicing.</h3>
<button>Yes</button><button>No</button>
</div>
<div class="question">
<h3>4. Lorem ipsum dolor sit amet, consectetur adipisicing.</h3>
<button>Yes</button><button>No</button>
</div>
<div class="question">
<h3>5. Lorem ipsum dolor sit amet, consectetur adipisicing.</h3>
<button>Yes</button><button>No</button>
</div>
<div class="question">
<h3>6. Lorem ipsum dolor sit amet, consectetur adipisicing.</h3>
<button>Yes</button><button>No</button>
</div>
<div class="question">
<h3>7. Lorem ipsum dolor sit amet, consectetur adipisicing.</h3>
<button>Yes</button><button>No</button>
</div>
<div class="question">
<h3>8. Lorem ipsum dolor sit amet, consectetur adipisicing.</h3>
<button>Yes</button><button>No</button>
</div>
<div class="question">
<h3>9. Lorem ipsum dolor sit amet, consectetur adipisicing.</h3>
<button>Yes</button><button>No</button>
</div>
</section>
</main>
<aside></aside>
<footer></footer>
</body>
For reference you may look at this question: 'position: sticky' not working when 'height' is defined

Related

list of things that i dont know how to make

so i kinda new on web development scene and there is something i want to know how to make, here is the list that i want to make
https://i.imgur.com/PAQaJde.png
what is that bar thing called? and how to make it stay on top when i scrolled
https://i.imgur.com/ai0Vf2g.png
is this card or simple col that get styled using css?
sorry for the dumb question guys, i really kinda lost since i dont know how those thing called
1) Its called a navigation, or a navBar, and you position it absolute at 0,0 for it to stay up the top:
2) not sure what you are asking for your second question but to get it in that style. you can use CSS Grid, or FlexBox which are both native browser functionality.
Im happy to answer any further questions :)
welcome to the community
The first one is a navbar or navigation bar. You can make it stick to the top by setting position: fixed; top: 0; left:0; z-index:99;
nav {
position: fixed;
display: block;
top: 0;
left: 0;
height: 50px;
width: 100%;
padding: 10px;
background-color: #ccc;
}
.block {
display: block;
height: 1000px;
}
<nav>
Navbar
</nav>
<div class='block'>
<p>Lorem ipsum dolor sit amet</p>
<p>Lorem ipsum dolor sit amet</p>
<p>Lorem ipsum dolor sit amet</p>
<p>Lorem ipsum dolor sit amet</p>
<p>Lorem ipsum dolor sit amet</p>
<p>Lorem ipsum dolor sit amet</p>
<p>Lorem ipsum dolor sit amet</p>
<p>Lorem ipsum dolor sit amet</p>
<p>Lorem ipsum dolor sit amet</p>
<p>Lorem ipsum dolor sit amet</p>
<p>Lorem ipsum dolor sit amet</p>
<p>Lorem ipsum dolor sit amet</p>
<p>Lorem ipsum dolor sit amet</p>
<p>Lorem ipsum dolor sit amet</p>
<p>Lorem ipsum dolor sit amet</p>
<p>Lorem ipsum dolor sit amet</p>
<p>Lorem ipsum dolor sit amet</p>
<p>Lorem ipsum dolor sit amet</p>
<p>Lorem ipsum dolor sit amet</p>
<p>Lorem ipsum dolor sit amet</p>
<p>Lorem ipsum dolor sit amet</p>
<p>Lorem ipsum dolor sit amet</p>
<p>Lorem ipsum dolor sit amet</p>
<p>Lorem ipsum dolor sit amet</p>
<p>Lorem ipsum dolor sit amet</p>
</div>
The second one you can achieve by nesting an element inst=ide another, applying a margin to the parent and border-radius to the child. It works with any layout style.
div{
border: solid 1px #ccc;
border-radius: 5px;
}
.container {
padding: 20px;
}
.card {
display: inline-block;
width: 100px;
height: 100px;
margin-right: 20px;
}
.card-wide {
display: inline-block;
width: 150px;
height: 50px;
margin-top: 30px;
margin-right: 30px;
}
<div class='container'>
<h1>Content</h1>
<div class='card'></div>
<div class='card'></div>
<div class='card'></div>
<br />
<div class='card-wide'></div>
<div class='card-wide'></div>
<div class='card-wide'></div>
<div class='card-wide'></div>
</div>

CSS only layout like masonry [duplicate]

This question already has answers here:
CSS-only masonry layout
(4 answers)
How to wrap flexbox over multiple rows and columns?
(3 answers)
Closed 4 years ago.
Question:
Is there any way to make layout like left to right masonry without JS?
! Please note I do not need exactly masonry, it works a bit different way !
Required:
Left to right order;
Each item goes to next column (items in masonry can pick columns out of order if available space on higher position);
Height is not fixed;
I can't change original order (1,2,3... but not 1,4,7...).
Example:
This one solution is almost what I looking for, but order is broken - example
HTML:
<div class="masonry">
<div class="item">1. (should be #1) ...</div>
<div class="item">2. (should be #4) ...</div>
<div class="item">3. (should be #7) Lorem ipsum dolor sit amet, consectetur adipisicing elit. Lorem ipsum dolor sit amet, consectetur adipisicing elit</div>
<div class="item">4. (should be #2) Lorem ipsum dolor sit amet, consectetur adipisicing. elit</div>
<div class="item">5. (should be #5) Lorem ipsum dolor sit asonsfd foindfosindf met, consectetur adipisicing elit.</div>
<div class="item">6. (should be #8) Lorem ipsum dolor sit amet, consectetur adipisicing. elit</div>
<div class="item">7. (should be #3) Lorem ipsum dolor sit amet, consectetur adipisicing elit.</div>
<div class="item">8. (should be #6) Lorem ipsum adipisicing elit. Lorem ipsum dolor sit elit</div>
<div class="item">9. (should be #9) Lorem ipsum dolor sit amet, consectetur adipisicing. elit</div>
</div>
CSS:
body {
font: 1em/1.67 'Open Sans', Arial, Sans-serif;
margin: 0;
background: #e9e9e9;
}
.wrapper {
width: 95%;
margin: 3em auto;
}
.masonry {
margin: 1.5em 0;
padding: 0;
-moz-column-gap: 1.5em;
-webkit-column-gap: 1.5em;
column-gap: 1.5em;
text-align:left;
font-size: .85em;
-moz-column-count: 3;
-webkit-column-count: 3;
column-count: 3;
}
.item {
display: inline-block;
background: #fff;
padding: 1em;
margin: 0 0 1.5em;
width: 100%;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-shadow: 2px 2px 4px 0 #ccc;
}
When ordering your html divs, you have to think differently.
If you draw your grid on a piece of paper, you can then draw rings around the columns and you get:
You want this:
1, 2, 3
4, 5, 6
7, 8, 9
You have to order like this:
1, 4, 7
2, 5, 8
3, 6, 9
Just re-order your html lines from columns to rows, like so:
<div class="masonry">
<div class="item">1. (should be #1) ...</div>
<div class="item">4. (should be #2) Lorem ipsum dolor sit amet, consectetur adipisicing. elit</div>
<div class="item">7. (should be #3) Lorem ipsum dolor sit amet, consectetur adipisicing elit.</div>
<div class="item">2. (should be #4) ...</div>
<div class="item">5. (should be #5) Lorem ipsum dolor sit asonsfd foindfosindf met, consectetur adipisicing elit.</div>
<div class="item">8. (should be #6) Lorem ipsum adipisicing elit. Lorem ipsum dolor sit elit</div>
<div class="item">3. (should be #7) Lorem ipsum dolor sit amet, consectetur adipisicing elit. Lorem ipsum dolor sit amet, consectetur adipisicing elit</div>
<div class="item">6. (should be #8) Lorem ipsum dolor sit amet, consectetur adipisicing. elit</div>
<div class="item">9. (should be #9) Lorem ipsum dolor sit amet, consectetur adipisicing. elit</div>
</div>

css columns: last column is not filled [duplicate]

This question already has answers here:
CSS column-count not respected
(4 answers)
Closed 5 years ago.
I am trying to use column-count css property to render divs in 4 columns.
But when there are 3n items (3, 6, 9...) in columns wrapper, only three columns get filled, and fourth column is empty!
CSS:
.columns {
-webkit-column-count: 4; /* Chrome, Safari, Opera */
-moz-column-count: 4; /* Firefox */
column-count: 4;
}
.item {
display: inline-block;
widtth: 100%;
border: 1px solid red;
}
HTML:
<div class="columns">
<div class="item">Lorem ipsum dolor sit amet 1</div><div class="item">Lorem ipsum dolor sit amet 2</div><div class="item">Lorem ipsum dolor sit amet 3</div>
<div class="item">Lorem ipsum dolor sit amet 4</div><div class="item">Lorem ipsum dolor sit amet 5</div><div class="item">Lorem ipsum dolor sit amet 6</div>
<div class="item">Lorem ipsum dolor sit amet 7</div><div class="item">Lorem ipsum dolor sit amet 8</div><div class="item">Lorem ipsum dolor sit amet 8</div>
</div>
Here is a JSFiddle.
How do I get elements in all 4 columns?
In your example, there are 9 elements of equal size to be distributed into 4 columns. Since they won't fit into 4 columns when the first column contains 2 elements (which would add up to a maximum of 8), the first column will contain 3 elements. That defines the height of the container, so the second column will also get 3 elements, and so there's also 3 remaining for the third column and none for the fourth column. There are four columns, but the fourth one is simply empty...
In other words: The height of the container is determined by the minimum height which is needed to fit all elements into the number of columns. Once that is done, the content will be filled into the columns starting from the left, and each column will get as much content as fits into it.
ADDITION AFTER COMMENT:
To get a distribution of elements as you want it, you have to insert empty DIVs - there is no other way (reason: read above):
.columns {
-webkit-column-count: 4;
/* Chrome, Safari, Opera */
-moz-column-count: 4;
/* Firefox */
column-count: 4;
}
.item {
display: inline-block;
width: 100%;
border: 1px solid red;
}
.empty {
display: inline-block;
}
<div class="columns">
<div class="item">Lorem ipsum dolor sit amet 1</div>
<div class="item">Lorem ipsum dolor sit amet 2</div>
<div class="item">Lorem ipsum dolor sit amet 3</div>
<div class="item">Lorem ipsum dolor sit amet 4</div>
<div class="item">Lorem ipsum dolor sit amet 5</div>
<div class="empty"></div>
<div class="item">Lorem ipsum dolor sit amet 6</div>
<div class="item">Lorem ipsum dolor sit amet 7</div>
<div class="empty"></div>
<div class="item">Lorem ipsum dolor sit amet 8</div>
<div class="item">Lorem ipsum dolor sit amet 8</div>
</div>
Try 'flexbox' display: flex and this now no problem :)
https://jsfiddle.net/bnmkzrkx/4/
I hope help :)
It is just a formatting issue. The column CSS is getting confused by the spaces in your code. Someone may be able to give a more technical explenation as to why this happens.
https://jsfiddle.net/bnmkzrkx/1/
.columns {
-webkit-column-count: 4; /* Chrome, Safari, Opera */
-moz-column-count: 4; /* Firefox */
column-count: 4;
}
.item {
display:inline-block;
border: 1px solid red;
}
<div class="columns">
<div class="item">Lorem ipsum dolor sit amet 2</div>
<div class="item">Lorem ipsum dolor sit amet 3</div>
<div class="item">Lorem ipsum dolor sit amet 4</div>
<div class="item">Lorem ipsum dolor sit amet 5</div>
<div class="item">Lorem ipsum dolor sit amet 6</div>
<div class="item">Lorem ipsum dolor sit amet 7</div>
<div class="item">Lorem ipsum dolor sit amet 8</div>
<div class="item">Lorem ipsum dolor sit amet 8</div>
</div>

Make a flexbox middle part scroll, without the container taking 100% of the page

Making a flexbox child have a scroll bar instead of growing, takes a container with fixed height.
easy to create in a an isolated environment:
#container {
height: 100%;
display: flex;
flex: 0 0 auto;
flex-flow: column;
}
#list {
display: flex;
flex-flow: column;
overflow: auto;
}
https://jsfiddle.net/1yjk5ojp/
but let's say i want to use a page header.
i don't know it's exact size, so i can't use aboslute position with mergin.
i also can't use any flex component along the way, cuz it's must be fixed size.
for example - added a 100px header
<div style="height: 100px;">
<h1>Page header</h1>
</div>
https://jsfiddle.net/z6dsq822/1/
is there anything i can do to make a fixed height component after an unknown size component?
my constrains are that i don't want another scroll bar, and i want the header to be outside this structure (it's a large application with different views, the header is in a template)
Make the parent container for everything a flex column and set #container to flex-grow: 1 so it takes up the available space, then everything else works as you already had it.
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
html,
body {
height: 100vh;
}
body {
display: flex;
flex-direction: column;
}
header {
flex: 0 0 100px;
}
#container {
display: flex;
flex-direction: column;
flex-grow: 1;
overflow: auto;
}
#list {
display: flex;
overflow: scroll;
flex-direction: column;
flex-grow: 1;
}
#top {
flex: 0 0 20px;
background-color: #db9277;
}
#bottom {
flex: 0 0 20px;
background-color: #db9277;
}
.row {
height: 100px;
background-color: #85d8d5;
}
<header>
header
</header>
<div id="container">
<div id="top"></div>
<div id="list">
<div class="row">Lorem ipsum dolor sit amet.</div>
<div class="row">Lorem ipsum dolor sit amet.</div>
<div class="row">Lorem ipsum dolor sit amet.</div>
<div class="row">Lorem ipsum dolor sit amet.</div>
<div class="row">Lorem ipsum dolor sit amet.</div>
<div class="row">Lorem ipsum dolor sit amet.</div>
<div class="row">Lorem ipsum dolor sit amet.</div>
<div class="row">Lorem ipsum dolor sit amet.</div>
<div class="row">Lorem ipsum dolor sit amet.</div>
<div class="row">Lorem ipsum dolor sit amet.</div>
<div class="row">Lorem ipsum dolor sit amet.</div>
<div class="row">Lorem ipsum dolor sit amet.</div>
<div class="row">Lorem ipsum dolor sit amet.</div>
<div class="row">Lorem ipsum dolor sit amet.</div>
<div class="row">Lorem ipsum dolor sit amet.</div>
<div class="row">Lorem ipsum dolor sit amet.</div>
<div class="row">Lorem ipsum dolor sit amet.</div>
<div class="row">Lorem ipsum dolor sit amet.</div>
<div class="row">Lorem ipsum dolor sit amet.</div>
<div class="row">Lorem ipsum dolor sit amet.</div>
<div class="row">Lorem ipsum dolor sit amet.</div>
<div class="row">Lorem ipsum dolor sit amet.</div>
<div class="row">Lorem ipsum dolor sit amet.</div>
<div class="row">Lorem ipsum dolor sit amet.</div>
<div class="row">Lorem ipsum dolor sit amet.</div>
<div class="row">Lorem ipsum dolor sit amet.</div>
<div class="row">Lorem ipsum dolor sit amet.</div>
<div class="row">Lorem ipsum dolor sit amet.</div>
<div class="row">Lorem ipsum dolor sit amet.</div>
<div class="row">Lorem ipsum dolor sit amet.</div>
<div class="row">Lorem ipsum dolor sit amet.</div>
<div class="row">Lorem ipsum dolor sit amet.</div>
<div class="row">Lorem ipsum dolor sit amet.</div>
<div class="row">Lorem ipsum dolor sit amet.</div>
</div>
<div id="bottom"></div>
</div>

How to horizontally scroll an inner div with text wrapping

I am trying to get a series of inner divs to scroll horizontally inside a fixed width outer div. I have it working but the only problem is the text in the inner div does not wrap and overflows the next div, because of the white-space:nowrap in the outer div, which accomplishes the scroll. How can I fix this so the inner divs continue to scroll rightward, but the text fits into the inner divs (red boxes)? Please have a look at this JSFiddle for the code:
Demo in Jsfiddle
HTML:
<div id="content">
<div id="contentHolder">
<div class="post">lorem ipsum dolor sit amet</div>
<div class="post">lorem ipsum dolor sit amet</div>
<div class="post">lorem ipsum dolor sit amet</div>
<div class="post">lorem ipsum dolor sit amet</div>
<div class="post">lorem ipsum dolor sit amet</div>
<div class="post">lorem ipsum dolor sit amet</div>
<div class="post">lorem ipsum dolor sit amet</div>
<div class="post">lorem ipsum dolor sit amet</div>
<div class="post">lorem ipsum dolor sit amet</div>
<div class="post">lorem ipsum dolor sit amet</div>
<div class="post">lorem ipsum dolor sit amet</div>
<div class="post">lorem ipsum dolor sit amet</div>
<div class="post">lorem ipsum dolor sit amet</div>
<div class="post">lorem ipsum dolor sit amet</div>
<div class="post">lorem ipsum dolor sit amet</div>
<div class="post">lorem ipsum dolor sit amet</div>
<div class="post">lorem ipsum dolor sit amet</div>
<div class="post">lorem ipsum dolor sit amet</div>
</div>
</div>
CSS:
#content {
margin:0px auto;
background-color:#515151;
width:600px;
border-radius:5px;
padding-top:20px;
}
#contentHolder {
color:#fff;
margin:0 auto;
width:500px;
height: 400px;
background-color:#000000;
border-radius:10px;
overflow:auto;
white-space:nowrap;
}
.post {
width:60px;
height:300px;
margin:10px;
display:inline-block;
font-size:12px;
background-color:#700;
}
Apply white-space: normal; to .post

Resources