Keep flex items fixed while resizing window - html

I am working on a web app and I need help with css. I am a beginner at css so please bear with me.
I'm trying to style a fixed sidebar for an app. The sidebar occupies the full height of the browser window. The whole sidebar is a flex box and the flex children are nested flex boxes as well.
Presently, the flex children move along with the browser window while reducing the viewport height and so the menu links get pushed up (but the avatar and username element remain fixed?!).
I don't want this to happen. The menu items inside the parent container should get clipped (instead of moving along with the browser window) and the user can scroll down to view the remaining menu items (like the sidebar on the youtube website for example).
For easy reference, here is the imgur link of what is current result and what I actually want: https://imgur.com/a/VShsF6o
Also, the scroll bar seems to take up extra width while appearing. Is there any way to stop that behavior?
https://jsfiddle.net/qbw1aLyz/8/
html {
background-color: #141E30;
margin: 0;
padding: 0;
}
.sidebar {
display: flex;
flex-direction: column;
width: 300px;
top: 0;
bottom: 0;
position: fixed;
overflow: auto;
background: #0a0c0f;
color: #EAE9E9;
}
.sidebar__profile {
padding: 16px;
display: flex;
flex-direction: column;
align-items: center;
}
.sidebar__menuitem {
padding-bottom: 10px;
display: flex;
align-items: center;
flex-shrink: 0;
height: 30px;
}
.count {
margin-left: auto;
margin-right: 20px;
border-radius: 6px;
padding: 2px 5px;
background-color: #EAE9E9;
color: #0a0c0f;
}
<div class="sidebar">
<div class="sidebar__profile">
<img src="http://chittagongit.com//images/avatar-icon/avatar-icon-4.jpg" height=50px alt="image" class="sidebar__profile__avatar" />
<div class="sidebar__profile__name">User Name</div>
</div>
<div class="sidebar__menuitem">
<div>Menu Item 1</div>
<div class="count">2</div>
</div>
<div class="sidebar__menuitem">
<div>Menu Item 2</div>
<div class="count">2</div>
</div>
<div class="sidebar__menuitem">
<div>Menu Item 3</div>
<div class="count">2</div>
</div>
<div class="sidebar__menuitem">
<div>Menu Item 4</div>
<div class="count">2</div>
</div>
<div class="sidebar__menuitem">
<div>Menu Item 5</div>
<div class="count">2</div>
</div>
<div class="sidebar__menuitem">
<div>Menu Item 6</div>
<div class="count">2</div>
</div>
<div class="sidebar__menuitem">
<div>Menu Item 7</div>
<div class="count">2</div>
</div>
</div>

Just wrap .sidebar__profile in another div so it can act as a block-element rather than a shrinking flex-element...
html {
background-color: #141E30;
margin: 0;
padding: 0;
}
.sidebar {
display: flex;
flex-direction: column;
width: 300px;
top: 0;
bottom: 0;
position: fixed;
overflow: auto;
background: #0a0c0f;
color: #EAE9E9;
}
.sidebar__profile {
padding: 16px;
display: flex;
flex-direction: column;
align-items: center;
}
.sidebar__menuitem {
padding-bottom: 10px;
display: flex;
align-items: center;
flex-shrink: 0;
height: 30px;
}
.count {
margin-left: auto;
margin-right: 20px;
border-radius: 6px;
padding: 2px 5px;
background-color: #EAE9E9;
color: #0a0c0f;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>title</title>
</head>
<body>
<div class="sidebar">
<div>
<div class="sidebar__profile">
<img src="http://chittagongit.com//images/avatar-icon/avatar-icon-4.jpg" height=50px alt="image" class="sidebar__profile__avatar" />
<div class="sidebar__profile__name">User Name</div>
</div>
</div>
<div class="sidebar__menuitem">
<div>Menu Item 1</div>
<div class="count">2</div>
</div>
<div class="sidebar__menuitem">
<div>Menu Item 2</div>
<div class="count">2</div>
</div>
<div class="sidebar__menuitem">
<div>Menu Item 3</div>
<div class="count">2</div>
</div>
<div class="sidebar__menuitem">
<div>Menu Item 4</div>
<div class="count">2</div>
</div>
<div class="sidebar__menuitem">
<div>Menu Item 5</div>
<div class="count">2</div>
</div>
<div class="sidebar__menuitem">
<div>Menu Item 6</div>
<div class="count">2</div>
</div>
<div class="sidebar__menuitem">
<div>Menu Item 7</div>
<div class="count">2</div>
</div>
</div>
</body>
</html>

Try wrapping the menu items in their own container, giving that container a scrolling function, and disabling shrinking on the profile.
Add this to your code:
nav {
overflow: auto;
}
.sidebar__profile {
align-self: center;
flex-shrink: 0;
}
revised jsfiddle demo

Related

How can I ensure that the top container only takes up as much space as the inner elements in all conditions?

<style>
.container{
background-color: lightgray;
text-align: center;
display: inline-block;
position: relative;
border-radius:5px;
}
.itemField{
margin-top:10px;
}
.item {
margin: 10px;
width: 20em;
vertical-align: top;
display:inline-block;
}
.itemInner {
width: 20em;
height: 5em;
margin: 0 auto;
padding: 0.83333333em;
border-width: 1px;
border-style: solid;
box-sizing: border-box;
text-align: left;
position: relative;
white-space: normal;
}
.itemInnerList{
width:fit-content;
background-color: beige;
}
</style>
<div class="container">
<div class="itemInnerList">
<div class="item">
<div class="itemInner ">
<div class="itemInnerText">
Item name 1
</div>
</div>
</div>
<div class="item">
<div class="itemInner ">
<div class="itemInnerText">
Item name 2
</div>
</div>
</div>
<div class="item">
<div class="itemInner ">
<div class="itemInnerText">
Item name 3
</div>
</div>
</div>
<div class="item">
<div class="itemInner ">
<div class="itemInnerText">
Item name 4
</div>
</div>
</div>
</div>
</div>
how can i make sure "itemInnerList" is just wide enough to wrap inner elements in all cases.
itemInnerList container shows like it's wide is 100% , not covers only inner elements .
i draw the boundry in image which i try to make.
i try to make container width, covers only inner elements in all screen width
enter image description here

How to apply css border-spacing to every other row?

I am building a css table using display: table that needs to satisfy two requirements
Bottom half of each row is custom content that spans full width of table
Visible margin between rows
I've tried messing with colspan and border spacing but haven't been able to make it work
Closest is using border-spacing and an additional table row, but I can't make the border-spacing only apply to every other row, and can't make my custom row full width of the table
<div class="table">
<div class="tr">
<div class="td">aaaa 1</div>
<div class="td">aaaa 2</div>
<div class="td">aaaa 3</div>
<div class="td">aaaa 4</div>
</div>
<div class="tr extra-info">
extra row of info
</div>
</div>
.tr {
display: table-row;
box-shadow: 0px 5px 12px red;
background-color: $white;
}
.td {
display: table-cell;
padding: 20px;
}
.extra-info {
display: table-cell;
height: 40px;
}
See https://codepen.io/joshuaohana/pen/VwzWbZp for non working example
I'd like to make the "extra row of info" in the codepen here
full width
connected to its row above so there's no margin or red border behind
How can I set this up with colspan or border-spacing or some other?
I am inserting another answer because I am unable to create a fiddle or codepen. So in this snippet, you can see that the margin is showing through the background, I suppose this is what you mean by that. I added another div, just above the table row, and included the extra-info in that div, and named it row1 and row 2 for each row and its extra-info. Now the key here is the display property "table-row-group" that allows us to cover row data and extra info in a div otherwise the width of the row is messed up. As for the spacing between the header and the rows+extra-info is concerned I "think" the best way is to use br below every div where you want to insert space.
.main{
margin: 20px;
border-collapse: separate;
}
.table {
display: table;
margin: auto;
width: 100%;
table-layout: auto;
}
.th {
display: table-row;
cursor: pointer;
}
.tr{
display: table-row;
cursor: pointer;
outline: 1px solid red;
}
.td {
display: table-cell;
text-align: left;
padding: 20px;
}
div .th {
outline: 2px solid black;
box-shadow: 0px 5px 12px black;
}
.extra-info{
display: table-row;
outline: 1px solid black;
height: 35px;
width: 100%;
}
.style{
color: black;
}
#row1{
display: table-row-group;
box-shadow: 0px 5px 12px black;
border-spacing: 0em 3rem;
}
#row2{
display: table-row-group;
box-shadow: 0px 5px 12px black;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="hw1.css">
</head>
<body>
<div class="main">
<div class="table">
<div class="th">
<div class="td">Heading 1</div>
<div class="td">Heading 2</div>
<div class="td">Heading 3</div>
<div class="td">Heading 4</div>
</div>
<br>
<div id="row1">
<div class="tr row">
<div class="td">aaaa 1</div>
<div class="td">aaaa 2</div>
<div class="td">aaaa 3</div>
<div class="td">aaaa 4</div>
</div>
<div class="tr extra-info">
extra row of info
</div>
</div>
<br>
<div id="row2">
<div class="tr row">
<div class="td">bbbb 1</div>
<div class="td">bbbb 2</div>
<div class="td">bbbb 3</div>
<div class="td">bbbb 4</div>
</div>
<div class="tr extra-info">
extra row of info
</div>
</div>
</div>
</body>
</html>
When you declare the width of the table the spacing between the table data is automatically calculated. You can make a div main to give it a box-shadow property. I have given a solid 1px black border to rows, if you want to give a border for columns you have to write the outline: 1px solid black in .td.
.main{
margin: 20px;
box-shadow: 0px 5px 12px red;
border-collapse: separate;
}
.table {
display: table;
margin: auto;
width: 100%;
table-layout: auto;
}
.th {
display: table-row;
cursor: pointer;
}
.tr{
display: table-row;
cursor: pointer;
outline: 1px solid red;
}
.td {
display: table-cell;
text-align: left;
padding: 20px;
}
div .th {
outline: 2px solid black;
}
.extra-info{
display: table-row;
outline: 1px solid black;
height: 35px;
width: 100%;
}
.style{
color: black;
}
.tr{
}
<div class="main">
<div class="table">
<div class="th">
<div class="td">Heading 1</div>
<div class="td">Heading 2</div>
<div class="td">Heading 3</div>
<div class="td">Heading 4</div>
</div>
<br>
<div class="tr">
<div class="td">aaaa 1</div>
<div class="td">aaaa 2</div>
<div class="td">aaaa 3</div>
<div class="td">aaaa 4</div>
</div>
<div class="tr extra-info">
extra row of info
</div>
<br>
<div class="tr">
<div class="td">bbbb 1</div>
<div class="td">bbbb 2</div>
<div class="td">bbbb 3</div>
<div class="td">bbbb 4</div>
</div>
<div class="tr extra-info">
extra row of info
</div>
</div>
</div>

CSS position: sticky not working inside a wrapper element

I'm trying CSS position: sticky property, it works in a simple parent and child structure. But, when I'm trying to implement it in a more complex parent and child HTML structure, it doesn't work as expected.
In example below, I want to make <div class="ribbon"> as sticky element with a parent div as sticky container named <div classs="element">, and its grandparent named <div class="viewport"> acts as the scrollable viewport. It should stick on the left: 0 whenever I scroll the viewport scrollbar, but it doesn't.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
white-space: nowrap;
}
html, body {
font-size: 14px;
}
div {
position: relative;
display: block;
}
.container {
display: inline-block;
}
.container > .viewport {
overflow: scroll;
}
.container > .viewport > .content {
padding: 1em;
}
.container > .viewport > .content > .element {
margin-bottom: 1em;
}
.ribbon {
position: -webkit-sticky;
position: sticky;
left: 0;
padding: .5em;
background-color: bisque;
}
.ribbon .item {
display: inline-block;
margin-right: .5em;
padding: .5em;
background-color: aqua;
}
.grid {
padding: .5em;
background-color: brown;
}
<div class="container" style="width: 40em">
<div class="viewport">
<div class="content">
<div class="element">
<div class="container ribbon" style="width: 50em">
<div class="viewport">
<div class="content">
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item">Item 3</div>
<div class="item">Item 4</div>
<div class="item">Item 5</div>
<div class="item">Item 6</div>
<div class="item">Item 7</div>
<div class="item">Item 8</div>
<div class="item">Item 9</div>
<div class="item">Item 10</div>
<div class="item">Item 11</div>
<div class="item">Item 12</div>
<div class="item">Item 13</div>
</div>
</div>
</div>
</div>
<div class="element">
<div class="grid">
<div class="content">
<h4>Grid content</h4>
<h4>Grid content</h4>
<h4>Grid content</h4>
<h4>Grid content</h4>
<h4>Grid content</h4>
<h4>Grid content</h4>
</div>
</div>
</div>
</div>
</div>
</div>
Is there anything wrong with this?

Switch between horizontal and vertical layout using CSS (Flex or CSS Grid)

I have a table which looks by default as follows (up to 20 categories with up to 30 items for each category; each of the items will be represented by a card):
Now I'd like to give the user the option to switch to a Horizontal Layout, which should look as follows.
I have started with a JSFiddle: https://jsfiddle.net/stefanwalther/1uzh836j/15/
.status-container {
}
.row {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.col {
display: flex;
flex-direction: column;
flex: 1;
border-width: 1px;
border-style: solid;
border-color: #ccc;
padding: 3px;
}
.header {
background-color: #ccc;
}
<div>
<div class="row header">
<div class="col">
Category 1
</div>
<div class="col">
Category 2
</div>
<div class="col">
Category 3
</div>
</div>
<div class="row">
<div class="col">
Item 1.1
</div>
<div class="col">
Item 2.1
</div>
<div class="col">
Item 3.1
</div>
</div>
<div class="row">
<div class="col">
Item 1.2
</div>
<div class="col">
Item 2.2
</div>
<div class="col">
Item 3.2
</div>
</div>
</div>
Unfortunately, I am stuck, don't know which approach to chose (CSS-Grid, Flex-Box, ?).
Pure CSS flex solution is here. Supports any number of items per category.
See the snippet below:
* {
box-sizing: border-box;
font: normal 400 100%/1.25 sans-serif;
}
#switch {
display: none
}
label {
display: inline-block;
margin: 1rem;
padding: .25em .5em;
border: solid 1px;
border-radius: 1em;
}
label:after {
content: 'vertical mode';
}
#switch:checked+label:after {
content: 'horizontal mode';
}
.category {
position: relative;
display: flex;
flex-wrap: wrap;
align-items: flex-start;
padding-left: 25%
}
.category > div {
width: 25%;
padding: .5em;
border: solid 2px rgba(0, 0, 0, 0);
border-width: 0 4px 4px 0;
box-shadow: inset 0 0 0 2px #248;
text-align: center;
}
.category .header {
position: absolute;
left: 0;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
color: #fff;
background: #27c padding-box;
box-shadow: none;
}
#switch:checked ~ section {
display: flex;
justify-content: stretch;
align-items: flex-start;
width: 100%;
}
#switch:checked ~ section .category {
flex-flow: column nowrap;
width: 25%;
padding: 0;
}
#switch:checked ~ section .category > div {
width: 100%
}
#switch:checked~section .category .header {
position: static;
height: auto;
}
<input type="checkbox" id="switch"><label for="switch">Switch to </label>
<section>
<div class="category">
<div class="header">Category 1</div>
<div>Item 1.1</div>
<div>Item 1.2</div>
<div>Item 1.3</div>
<div>Item 1.4</div>
<div>Item 1.5</div>
<div>Item 1.6</div>
<div>Item 1.7</div>
<div>Item 1.8</div>
</div>
<div class="category">
<div class="header">Category 2</div>
<div>Item 2.1</div>
<div>Item 2.2</div>
<div>Item 2.3</div>
</div>
<div class="category">
<div class="header">Category 3</div>
<div>Item 3.1</div>
<div>Item 3.2</div>
<div>Item 3.3</div>
<div>Item 3.4</div>
<div>Item 3.5</div>
<div>Item 3.6</div>
<div>Item 3.7</div>
<div>Item 3.8</div>
<div>Item 3.9</div>
<div>Item 3.10</div>
<div>Item 3.11</div>
<div>Item 3.12</div>
<div>Item 3.13</div>
<div>Item 3.14</div>
</div>
<div class="category">
<div class="header">Category 4</div>
<div>Item 4.1</div>
<div>Item 4.2</div>
<div>Item 4.3</div>
<div>Item 4.4</div>
</div>
</section>

Div needs to be centered [duplicate]

This question already has answers here:
Center a column using Twitter Bootstrap 3
(34 answers)
How do you get centered content using Twitter Bootstrap?
(24 answers)
Closed 4 years ago.
See the blank space I marked with red arrow, I want these divs to be centered. But it's floating to left. I placed all these divs to middleBox div and in middleBox I styled text-align: center but nothing worked.
Help me out guys
My HTML
#middleBoxMargin {
margin-top: 80px;
}
#middleBox {
text-align: center;
}
#groupInsurance {
background-color: #EEEEEE;
text-align: center;
height: 145px;
}
#lifeInsurance {
background-color: #EEEEEE;
text-align: center;
height: 145px;
}
#dentalInsurance {
background-color: #EEEEEE;
text-align: center;
height: 145px;
}
#replacementInsurance {
background-color: #EEEEEE;
text-align: center;
height: 145px;
}
<div class="container">
<div class="row">
<div class="col-sm-12" id="middleBoxMargin">
<div id="middleBox">
<div class="col-sm-2">
<div id="groupInsurance"></div>
</div>
<div class="col-sm-2">
<div id="lifeInsurance"></div>
</div>
<div class="col-sm-2">
<div id="dentalInsurance"></div>
</div>
<div class="col-sm-2">
<div id="replacementInsurance"></div>
</div>
</div>
</div>
</div>
</div>
Add
display: flex;
justify-content: center;
#middleBoxMargin {
margin-top: 80px;
}
#middleBox {
display: flex;
justify-content: center;
}
#groupInsurance {
background-color: #EEEEEE;
text-align: center;
height: 145px;
}
#lifeInsurance {
background-color: #EEEEEE;
text-align: center;
height: 145px;
}
#dentalInsurance {
background-color: #EEEEEE;
text-align: center;
height: 145px;
}
#replacementInsurance {
background-color: #EEEEEE;
text-align: center;
height: 145px;
}
<div class="container">
<div class="row">
<div class="col-sm-12" id="middleBoxMargin">
<div id="middleBox">
<div class="col-sm-2">
<div id="groupInsurance"></div>
</div>
<div class="col-sm-2">
<div id="lifeInsurance"></div>
</div>
<div class="col-sm-2">
<div id="dentalInsurance"></div>
</div>
<div class="col-sm-2">
<div id="replacementInsurance"></div>
</div>
</div>
</div>
</div>
</div>
If you are using boostrap 4, adding a class justify-content-md-center to the div with row class would do the job. But seems like you are using bootstrap 3, so you can use the offset class. Try updating your code this way.
<div class="container">
<div class="row">
<div class="col-sm-12" id="middleBoxMargin">
<div class="row" id="middleBox">
<div class="col-sm-2 col-sm-offset-2">
<div id="groupInsurance"></div>
</div>
<div class="col-sm-2">
<div id="lifeInsurance"></div>
</div>
<div class="col-sm-2">
<div id="dentalInsurance"></div>
</div>
<div class="col-sm-2">
<div id="replacementInsurance"></div>
</div>
</div>
</div>
</div>
</div>
you can use flex for that
#middleBox {
display: flex;
justify-content:center
}
.col {
padding: 0 15px;
}
.box {
background-color: #EEEEEE;
text-align: center;
height: 100px;
width: 100px;
}
<div class="container">
<div id="middleBox">
<div class="col">
<div id="groupInsurance" class="box"></div>
</div>
<div class="col">
<div id="lifeInsurance" class="box"></div>
</div>
<div class="col">
<div id="dentalInsurance" class="box"></div>
</div>
<div class="col">
<div id="replacementInsurance" class="box"></div>
</div>
</div>
</div>
or even better you can use grid
#middleBox {
display: grid;
grid-template-columns: repeat(4, 100px);
grid-gap: 15px;
justify-content: center;
}
.box {
background-color: #EEEEEE;
text-align: center;
height: 100px;
width: 100%;
}
<div class="container">
<div id="middleBox">
<div id="groupInsurance" class="box"></div>
<div id="lifeInsurance" class="box"></div>
<div id="dentalInsurance" class="box"></div>
<div id="replacementInsurance" class="box"></div>
</div>
</div>
I'll do that kind of things:
div {
border: 1px solid black;
}
#middleBoxMargin {
margin-top: 80px;
}
#middleBox {
display: flex;
justify-content: center;
}
#middleBox > div {
background-color: #EEEEEE;
text-align: center;
height: 145px;
width: 20%;
margin: 5px 10px;
}
<div class="container">
<div class="row">
<div class="col-sm-12" id="middleBoxMargin">
<div id="middleBox">
<div class="col-sm-2">
<div id="groupInsurance"></div>
</div>
<div class="col-sm-2">
<div id="lifeInsurance"></div>
</div>
<div class="col-sm-2">
<div id="dentalInsurance"></div>
</div>
<div class="col-sm-2">
<div id="replacementInsurance"></div>
</div>
</div>
</div>
</div>
</div>
Note that the CSS is shorter, and some of your classes in html useless now.