Overflow-x stops working when I add overflow-y - html

.scrollable-items {
height: 100px;
overflow-x: unset;
overflow-y: auto;
width: 60px;
}
.cx-mainnav-hoverwrapper {
position: relative;
}
.cx-mainnav-hoverlabel {
display: inline;
position: absolute;
top: 0;
left: 50px;
margin-top: 10px;
opacity: 0;
pointer-events: none;
display: none;
}
.cx-mainnav:hover + .cx-mainnav-hoverlabel {
opacity: 1;
display: block;
}
<div class="scrollable-items">
<div class="cx-mainnav-hoverwrapper">
<div class="cx-mainnav">Icon 1</div>
<div class="cx-mainnav-hoverlabel">Icon 1 Tooltip</div>
</div>
<div class="cx-mainnav-hoverwrapper">
<div class="cx-mainnav">Icon 2</div>
<div class="cx-mainnav-hoverlabel">Icon 2 Tooltip</div>
</div>
<div class="cx-mainnav-hoverwrapper">
<div class="cx-mainnav">Icon 3</div>
<div class="cx-mainnav-hoverlabel">Icon 3 Tooltip</div>
</div>
<div class="cx-mainnav-hoverwrapper">
<div class="cx-mainnav">Icon 4</div>
<div class="cx-mainnav-hoverlabel">Icon 4 Tooltip</div>
</div>
<div class="cx-mainnav-hoverwrapper">
<div class="cx-mainnav">Icon 5</div>
<div class="cx-mainnav-hoverlabel">Icon 5 Tooltip</div>
</div>
Basically, I have one vertical navigation bar
Before adding scrollbar-y, I used to see tooltip on hovering on element in left side of icon.
But, once I added overflow-y as auto, now I can't see tooltip on hover in left side of icon.
In this context, I want to add scrollbar on y axis, but I want to show tooltip as well in left side of icon when I hover over element. Currently, I am not able to achieve both things at same time.

You could unset the overflow-y on hover.
.scrollable-items {
min-height: 300px;
overflow-x: unset;
overflow-y: auto;
width: 50px;
}
.scrollable-items:hover {
overflow-y: unset;
}
.cx-mainnav-hoverwrapper {
position: relative;
}
.cx-mainnav-hoverlabel {
display: inline;
position: absolute;
top: 0;
left: 50px;
margin-top: 10px;
opacity: 0;
pointer-events: none;
}
.cx-mainnav:hover+.cx-mainnav-hoverlabel {
opacity: 1;
}
<div class="scrollable-items">
<div class="cx-mainnav-hoverwrapper">
<div class="cx-mainnav">Icon 1</div>
<div class="cx-mainnav-hoverlabel">Icon 1 Tooltip</div>
</div>
<div class="cx-mainnav-hoverwrapper">
<div class="cx-mainnav">Icon 2</div>
<div class="cx-mainnav-hoverlabel">Icon 2 Tooltip</div>
</div>
<div class="cx-mainnav-hoverwrapper">
<div class="cx-mainnav">Icon 3</div>
<div class="cx-mainnav-hoverlabel">Icon 3 Tooltip</div>
</div>
<div class="cx-mainnav-hoverwrapper">
<div class="cx-mainnav">Icon 4</div>
<div class="cx-mainnav-hoverlabel">Icon 4 Tooltip</div>
</div>
<div class="cx-mainnav-hoverwrapper">
<div class="cx-mainnav">Icon 5</div>
<div class="cx-mainnav-hoverlabel">Icon 5 Tooltip</div>
</div>
You'll have to decide whether that is good enough for your real life case (the scrollbar disappearing on hover for example).

.scrollable-items {
min-height: 100px;
overflow-x: unset;
overflow-y: auto;
width: 60px;
}
.cx-mainnav-hoverlabel {
display: inline;
position: absolute;
left: 50px;
opacity: 0;
pointer-events: none;
padding: 2px 3px;
border-radius: 3px;
}
.cx-mainnav:hover + .cx-mainnav-hoverlabel {
background-color: crimson;
color: white;
opacity: 1;
display: block;
}
<div class="scrollable-items">
<div class="cx-mainnav-hoverwrapper">
<div class="cx-mainnav">Icon 1</div>
<div class="cx-mainnav-hoverlabel">Icon 1 Tooltip</div>
</div>
<div class="cx-mainnav-hoverwrapper">
<div class="cx-mainnav">Icon 2</div>
<div class="cx-mainnav-hoverlabel">Icon 2 Tooltip</div>
</div>
<div class="cx-mainnav-hoverwrapper">
<div class="cx-mainnav">Icon 3</div>
<div class="cx-mainnav-hoverlabel">Icon 3 Tooltip</div>
</div>
<div class="cx-mainnav-hoverwrapper">
<div class="cx-mainnav">Icon 4</div>
<div class="cx-mainnav-hoverlabel">Icon 4 Tooltip</div>
</div>
<div class="cx-mainnav-hoverwrapper">
<div class="cx-mainnav">Icon 5</div>
<div class="cx-mainnav-hoverlabel">Icon 5 Tooltip</div>
</div>
</div>

I hope this answers you question. (the comments section is always open)
.scrollable-items {
width: 100px;
height: 90px;
/* position: relative; */
overflow-y: auto;
/* to make it scrollable 'y' only */
overflow-x: hidden;
font-size: 1.5rem;
}
.cx-mainnav {
/*position: relative;*/
display: inline;
}
.cx-mainnav-hoverwrapper {
/* position: relative; */
position: absolute;
visibility: hidden;
}
.cx-mainnav-hoverlabel {
display: block;
position: relative;
font-size: 1.1rem;
}
.cx-mainnav:hover .cx-mainnav-hoverwrapper {
visibility: visible;
opacity: 1;
}
<div class="scrollable-items">
<div class="cx-mainnav">
<span>Icon 1</span>
<span class="cx-mainnav-hoverwrapper"><span class="cx-mainnav-hoverlabel">Icon 1 tooltip</span></span>
</div>
<div class="cx-mainnav">
<span>Icon 2</span>
<span class="cx-mainnav-hoverwrapper"><span class="cx-mainnav-hoverlabel">Icon 2 tooltip</span></span>
</div>
<div class="cx-mainnav">
<span>Icon 3</span>
<span class="cx-mainnav-hoverwrapper"><span class="cx-mainnav-hoverlabel">Icon 3 tooltip</span></span>
</div>
<div class="cx-mainnav">
<span>Icon 4</span>
<span class="cx-mainnav-hoverwrapper"><span class="cx-mainnav-hoverlabel">Icon 4 tooltip</span></span>
</div>
<div class="cx-mainnav">
<span>Icon 5</span>
<span class="cx-mainnav-hoverwrapper"><span class="cx-mainnav-hoverlabel">Icon 5 tooltip</span></span>
</div>
</div>
The reason you see tooltip 4 and 5 a little off positioned is because of real and pseudo positioning (that is because of scrolling).

Related

Why isn't row-gap working on the left grid?

I have two separate one-column grids side by side. The html layout is the same for both grids but in css the grid on the left is not showing row-gap on the webpage.
html:
<div class="both-grids">
<div class="show-grid-container">
<div class="grid-item">show 1</div>
<div class="grid-item">show 2</div>
<div class="grid-item">show 3</div>
<div class="grid-item">show 4</div>
<div class="grid-item">show 5</div>
</div>
<div class="movie-grid-container">
<div class="grid-item">movie 1</div>
<div class="grid-item">movie 2</div>
<div class="grid-item">movie 3</div>
<div class="grid-item">movie 4</div>
<div class="grid-item">movie 5</div>
</div>
</div>
css:
.both-grids {
padding-left: 100px;
}
.show-grid-container, .movie-grid-container {
display: inline-grid;
grid-template-rows: 40px 200px 200px 200px 200px;
row-gap: 40px;
}
.movie-grid-container {
padding-left: 80px;
}
.show-grid-container, .movie-grid-container > div {
background-color: black;
padding-right: 80px;
padding-left: 80px;
}
You are missing > div on .show-grid-container in the last piece of CSS
.both-grids {
padding-left: 100px;
}
.show-grid-container, .movie-grid-container {
display: inline-grid;
grid-template-rows: 40px 200px 200px 200px 200px;
row-gap: 40px;
}
.movie-grid-container {
padding-left: 80px;
}
.show-grid-container >div, .movie-grid-container >div {
background-color: black;
padding-right: 80px;
padding-left: 80px;
color:white;
}
<div class="both-grids">
<div class="show-grid-container">
<div class="grid-item">show 1</div>
<div class="grid-item">show 2</div>
<div class="grid-item">show 3</div>
<div class="grid-item">show 4</div>
<div class="grid-item">show 5</div>
</div>
<div class="movie-grid-container">
<div class="grid-item">movie 1</div>
<div class="grid-item">movie 2</div>
<div class="grid-item">movie 3</div>
<div class="grid-item">movie 4</div>
<div class="grid-item">movie 5</div>
</div>
</div>
Use this in css
.show-grid-container >div, .movie-grid-container >div {}
instead of
yours -> .show-grid-container, .movie-grid-container > 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?

Trello alike CSS layout

I'm trying to accomplish a layout similar to Trello:
kanban is always fully visible.
lane shrinks to fit the cardList.
cardList overflows when it reaches the bottom of kanban
kanban overflows horizontally when lanes are out of sight.
I'm not sure how to overflow the cardList component. I know it currently doesn't work because of the height: 100% property within .cardList, but I'd like to not have to give it a fixed height.
Also, I can't seem to overflow the kanban horizontally when I add overflow-x: scroll to .kanban.
Here's also a codesandbox in case it's easier.
:root {
--padding-card: 4px;
}
.App {
font-family: sans-serif;
text-align: center;
}
.container {
height: 90vh;
}
.kanbanWrapper {
background: black;
height: 100%;
overflow: hidden;
}
.kanban {
display: inline-flex;
background: lightgrey;
border-radius: 4px;
padding: 1rem;
margin: 1rem;
}
.kanban .lane {
margin: 0 var(--padding-card);
}
.lane {
height: 100%;
display: flex;
flex-direction: column;
background: lightpink;
width: 200px;
overflow: auto;
}
.laneHeader {
font-weight: bold;
border: 1px solid black;
padding: 0.5rem 0;
}
.laneFooter {
font-weight: bold;
border: 1px solid green;
}
.cardList {
padding: 4px;
min-height: 150px;
display: flex;
flex-direction: column;
height: 100%;
overflow: auto;
border: 1px solid blue;
}
.cardList .card {
margin: var(--padding-card);
}
.card {
background: lightgreen;
border-radius: 4px;
padding: 1rem 2rem;
}
<div class="App container">
<div class="kanbanWrapper">
<div class="kanban">
<div class="lane">
<div class="laneHeader">To do</div>
<div class="cardList">
<div class="card">Card 1 Longer title...</div>
<div class="card">Card 2</div>
<div class="card">Card 3</div>
<div class="card">Card 4</div>
<div class="card">Card 5</div>
<div class="card">Card 6</div>
<div class="card">Card 7</div>
<div class="card">Card 8</div>
<div class="card">Card 9</div>
<div class="card">Card 10</div>
<div class="card">Card 11</div>
<div class="card">Card 12</div>
</div>
<div class="laneFooter">+ Add card</div>
</div>
<div class="lane">
<div class="laneHeader">Doing</div>
<div class="cardList">
<div class="card">Card 11</div>
<div class="card">Card 12</div>
<div class="card">Card 13</div>
<div class="card">Card 14</div>
<div class="card">Card 15</div>
<div class="card">Card 16</div>
<div class="card">Card 17</div>
</div>
<div class="laneFooter">+ Add card</div>
</div>
<div class="lane">
<div class="laneHeader">Done</div>
<div class="cardList">
<div class="card">Card 21</div>
<div class="card">Card 22</div>
</div>
<div class="laneFooter">+ Add card</div>
</div>
<div class="lane">
<div class="laneHeader">Quality</div>
<div class="cardList"></div>
<div class="laneFooter">+ Add card</div>
</div>
</div>
</div>
</div>

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>

Make element inside element with position sticky above other sticky elements

In the example below:
.item {
width: 100%;
}
.item-header {
display: flex;
flex-direction: column;
background-color: red;
position: sticky;
z-index: 10;
top: 0;
}
.title {
order: 2;
}
.item-header-right {
order: 1;
margin-left: auto;
}
.item-header-right-placeholder {
width: 100%;
height: 18px;
background-color: red;
}
<div class="item">
<div class="item-header">
<div class="title">hello</div>
<div class="item-header-right">hello</div>
</div>
<br><br><br><br><br><br><br><br><br><br><br><br>
</div>
<div class="item">
<div class="item-header">
<div class="title">hello</div>
<div class="item-header-right-placeholder"></div>
</div>
<br><br><br><br><br><br><br><br><br><br><br><br>
</div>
<div class="item">
<div class="item-header">
<div class="title">hello</div>
<div class="item-header-right-placeholder"></div>
</div>
<br><br><br><br><br><br><br><br><br><br><br><br>
</div>
<div class="item">
<div class="item-header">
<div class="title">hello</div>
<div class="item-header-right-placeholder"></div>
</div>
<br><br><br><br><br><br><br><br><br><br><br><br>
</div>
<div class="item">
<div class="item-header">
<div class="title">hello</div>
<div class="item-header-right-placeholder"></div>
</div>
<br><br><br><br><br><br><br><br><br><br><br><br>
</div>
I would like to make it so the top right 'hello' always stays above the other sticky elements when going over them. Is this possible?
Here's the jsfiddle if its easier to edit there:
https://jsfiddle.net/azyfcn7m/
Depends on your remaining structure but this is one way to do it. You make the item position: fixed;
* {
box-sizing: border-box;
}
body {
margin: 0;
padding: 0;
}
.item {
width: 100%;
}
.item-header {
display: flex;
flex-direction: column;
background-color: red;
position: sticky;
z-index: 1;
top: 0;
}
.title {
order: 2;
}
.item-header-right {
order: 1;
margin-left: auto;
}
.item-header-right-placeholder {
width: 100%;
height: 18px;
background-color: red;
}
.fixed-item {
position: fixed;
top: 0;
right: 0;
padding: .25rem;
background-color: deepskyblue;
z-index: 2;
}
<div class="fixed-item">hello</div>
<div class="item">
<div class="item-header">
<div class="title">hello</div>
</div>
<br><br><br><br><br><br><br><br><br><br><br><br>
</div>
<div class="item">
<div class="item-header">
<div class="title">hello</div>
<div class="item-header-right-placeholder"></div>
</div>
<br><br><br><br><br><br><br><br><br><br><br><br>
</div>
<div class="item">
<div class="item-header">
<div class="title">hello</div>
<div class="item-header-right-placeholder"></div>
</div>
<br><br><br><br><br><br><br><br><br><br><br><br>
</div>
<div class="item">
<div class="item-header">
<div class="title">hello</div>
<div class="item-header-right-placeholder"></div>
</div>
<br><br><br><br><br><br><br><br><br><br><br><br>
</div>
<div class="item">
<div class="item-header">
<div class="title">hello</div>
<div class="item-header-right-placeholder"></div>
</div>
<br><br><br><br><br><br><br><br><br><br><br><br>
</div>