Row submenu appears in wrong place after click [duplicate] - javascript

This question already has answers here:
Position absolute but relative to parent
(5 answers)
Closed 2 years ago.
I have static top bar and left menu, and scrollable long content on right. In my (long) submenu I use position: absolute to not change row height. Submenu position for rows 2 and 3 in below snippet is wrong and non-intuitive and unwanted scroll bar appear. How to fix it?
body { margin: 0}
button { height: 20px}
.hide { display:none; }
.container { display: flex; }
.topBar { background: red; height: 30px; }
.side__menu {
height: calc(100vh - 30px);
background: yellow;
display: flex;
flex-direction: column;
justify-content: space-between;
width:100px;
}
.main__panel {
overflow: auto;
height: calc(100vh - 30px);
width: calc(100vw - 100px);
}
.row {
display: flex;
justify-content: space-between;
align-items: center;
height: 200px;
background: #ddd;
margin: 10px;
}
.submenu {
position: absolute;
right: 100px;
background: #fdd;
height: 70px;
}
<div class="topBar">Top Bar</div>
<div class="container">
<div class="side__menu">
<div>item1</div><div>item2</div><div>menu footer</div>
</div>
<div class="main__panel">
<div class="row">
Row 1
<button onclick="s1.classList.toggle('hide')">toggle submenu</button>
<div id="s1" class="submenu hide">submenu</div>
</div>
<div class="row">
Row 2
<button onclick="s2.classList.toggle('hide')">toggle submenu</button>
<div id="s2" class="submenu hide">submenu</div>
</div>
<div class="row">
Row 3
<button onclick="s3.classList.toggle('hide')">toggle submenu</button>
<div id="s3" class="submenu hide">submenu</div>
</div>
</div>
</div>

I make some investigation and discover that height: 100vh (with calc or not) "create problems" with submenu. I accidentally find one solution - just add following style to row class
position: relative;
But I totally don't know why it actually works - so feel free to create answer and explain it if you know why (or show some alternative approach)
body { margin: 0}
button { height: 20px}
.hide { display:none; }
.container { display: flex; }
.topBar { background: red; height: 30px; }
.side__menu {
height: calc(100vh - 30px);
background: yellow;
display: flex;
flex-direction: column;
justify-content: space-between;
width:100px;
}
.main__panel {
overflow: auto;
height: calc(100vh - 30px);
width: calc(100vw - 100px);
}
.row {
display: flex;
justify-content: space-between;
align-items: center;
height: 200px;
background: #ddd;
margin: 10px;
position: relative;
}
.submenu {
position: absolute;
right: 100px;
background: #fdd;
height: 70px;
}
<div class="topBar">Top Bar</div>
<div class="container">
<div class="side__menu">
<div>item1</div><div>item2</div><div>menu footer</div>
</div>
<div class="main__panel">
<div class="row">
Row 1
<button onclick="s1.classList.toggle('hide')">toggle submenu</button>
<div id="s1" class="submenu hide">submenu</div>
</div>
<div class="row">
Row 2
<button onclick="s2.classList.toggle('hide')">toggle submenu</button>
<div id="s2" class="submenu hide">submenu</div>
</div>
<div class="row">
Row 3
<button onclick="s3.classList.toggle('hide')">toggle submenu</button>
<div id="s3" class="submenu hide">submenu</div>
</div>
</div>
</div>
Tested on: Chrome, Safari and Firefox

Related

positioning div after it has been rotated

I would like to make a div with 3 texts, rotate it and place it on a fixed spot on the page. I would like it to perfectly fit the size of the screen,
So I created a div which height and width were the opposite of what I need then I rotated it. The thing is that I'm having problems positioning it correctly on the spot I want. (top:0 right:40px)
This is my code where I tried to move the div around.
.page {
width: 100%;
heigth: 100%;
background-color: #fefefe;
}
.green-band {
height: 90px;
width: 100vh;
padding: 0 30px;
background-color: green;
display: flex;
justify-content: space-between;
align-items: center;
transform: rotate(-90deg);
position: fixed;
top: 0;
right: 40px;
}
<div class="page"></div>
<div class="green-band">
<div class="text-inside">Text 1</div>
<div class="text-inside">Text 2</div>
<div class="text-inside">Text 3</div>
</div>
Can you help me figuring out how to correctly position the div?
.page {
width: 100%;
heigth: 100%;
background-color: #fefefe;
}
.green-band {
height: 90px;
width: 100vh;
padding: 0 30px;
background-color: green;
display: flex;
justify-content: space-between;
align-items: center;
transform: translateX(calc(100% - 40px)) rotate(-90deg);
transform-origin: bottom left;
position: fixed;
bottom: 0;
right: 0;
}
<div class="page"></div>
<div class="green-band">
<div class="text-inside">Text 1</div>
<div class="text-inside">Text 2</div>
<div class="text-inside">Text 3</div>
</div>

Align text in the center by ignoring the absolutely positioned element

I am developing a flex table from scratch and the table supports filtering and sorting. The icons for filters and sorting are displayed in the table header (right corner). Also my table supports that the user can position the header text left/center;
My problem:
Since the icons are inside the table header, icons as well occupies some space. So when i position the elements in the center, i see the alignment gets disturbed as shown below.
body {
width: 100%;
}
.table-header, .table-body {
display: flex;
width: fit-content;
border: 1px solid black;
padding: 10px;
}
.header, .data {
display: flex;
min-width: 150px;
width: 150px;
border-right: 1px solid black;
display: flex;
justify-content: center;
position: relative;
}
.header .text {
width: 100%;
white-space: nowrap;
text-align: center;
overflow: hidden;
text-overflow: ellipsis;
}
.icons {
float: right;
right: 0;
display: flex;
}
<div class="table">
<div class="table-header">
<div class="header">
<div class="text">Hlkjklkjlkjlkj lkjlkjlkjlkjlkjljlkjlkj</div>
<div class="icons">
<span> &#9760</span>
<span> &#9760</span>
</div>
</div>
<div class="header">9747
<div class="text">Header 2</div>
<div class="icons">
<span>b</span>
<span>b</span>
</div>
</div>
<div class="header">
<div class="text">Header 3</div>
<div class="icons">
<span>a</span>
<span>b</span>
</div>
</div>
<div class="header">
<div class="text">Header 4</div>
<div class="icons">
<span>a</span>
<span>b</span>
</div>
</div>
</div>
<div class="table-body">
<div class="data">123</div>
<div class="data">123</div>
<div class="data">123</div>
<div class="data">123</div>
</div>
<div class="table-body">
<div class="data">123</div>
<div class="data">123</div>
<div class="data">123</div>
<div class="data">123</div>
</div><div class="table-body">
<div class="data">123</div>
<div class="data">123</div>
<div class="data">123</div>
<div class="data">123</div>
</div>
</div>
Code: Here
What i tried
So since the icons as well take some space, to avoid this i positioned them absolutely relative to the header. So the alignment problem got solved . But for long headers where ellipsis has to be shown, the ellipsis hides behind the icons as shown below
Code: Here
So what is the solution to this ? I want to maintain the center position by reducing the space occupied by the icons. Is it possible through CSS? Please help. Thanks :)
If you try to do that with absolute positioning you need to know what exact width your icons can take.
Then possible solution is to add padding rule (left/right) into table headers, so CSS code should be like this:
body {
width: 100%;
}
.table-header, .table-body {
display: flex;
width: fit-content;
border: 1px solid black;
padding: 10px;
}
.header, .data {
box-sizing: border-box;
padding: 0 30px;
display: flex;
min-width: 150px;
width: 150px;
border-right: 1px solid black;
display: flex;
justify-content: center;
position: relative;
}
.header .text {
width: 100%;
white-space: nowrap;
text-align: center;
overflow: hidden;
text-overflow: ellipsis;
}
.icons {
position: absolute;
right: 0;
}

How to struct a Gantt Chart using flex divs using HTML and CSS

I'm structuring a Gantt Chart component using CSS and HTML.
The below image illustrate the necessary user viewing interactions:
The red boundaries is the current user view. The desired scrolling behaviour is as follows:
a) The tasks are must be scrolled vertically and horizontally as data can be out of viewable area.
b) When scrolling horizontally, the scale must be scrolled in sync (the scale will have date/time tags).
c) When scrolling horizontally, the left title boxes must remain fixed on the left, not scrolling together.
d) When scrolling vertically, the scale must remain fixed at the top.
e) When scrolling vertically, the titles boxes scrolls together with taks, keeping in sync view.
Here is what've tried so far with no success.
.container {
height: 100vh;
width: 100vw;
background-color: #cdcdcd;
}
.areas {
display: flex;
flex-direction: row;
justify-content: space-between;
height: 100%;
}
.leftarea {
display: flex;
flex-direction: column;
background-color: #ababab;
height: 100%;
margin-top: 30px;
}
.rightarea {
display: flex;
flex-direction: column;
height: 100%;
}
.titlecard {
display: flex;
justify-content: center;
align-items: center;
width: 50px;
min-height: 30px;
background-color: #435543;
color: white;
margin: 10px;
}
.scale {
display: flex;
color: white;
background-color: #433777;
}
.scaletick {
display: flex;
justify-content: center;
align-items: center;
height: 30px;
width: 80px;
color: white;
border: 1px solid white;
}
.tasks {
display: flex;
flex-direction: column;
background-color: #393984;
height: 100%;
}
.taskcard {
display: flex;
justify-content: center;
align-items: center;
background-color: #fefefe;
border-radius: 4px;
padding: 5px;
height: 50px;
width: 100px;
margin: 10px;
}
.taskcard1 {
width: 100px;
margin-left: 80px;
}
.taskcard2 {
width: 550px;
margin-left: 230px;
}
.taskcard3 {
width: 400px;
margin-left: 40px;
}
.taskcard4 {
width: 300px;
margin-left: 130px;
}
.taskcard5 {
width: 350px;
margin-left: 400px;
}
.taskcard6 {
width: 90px;
margin-left: 90px;
}
.taskcard7 {
width: 70px;
margin-left: 230px;
}
.taskcard8 {
width: 150px;
margin-left: 10px;
}
.taskcard9 {
width: 60px;
margin-left: 120px;
}
.taskcard10 {
width: 50px;
margin-left: 45px;
}
<div class="container">
<div class="areas">
<div class="leftarea">
<div class="titlecard">
Title 1
</div>
<div class="titlecard">
Title 2
</div>
<div class="titlecard">
Title 3
</div>
<div class="titlecard">
Title 4
</div>
<div class="titlecard">
Title 5
</div>
<div class="titlecard">
Title 6
</div>
<div class="titlecard">
Title 7
</div>
<div class="titlecard">
Title 8
</div>
<div class="titlecard">
Title 9
</div>
<div class="titlecard">
Title 10
</div>
</div>
<div class="rightarea">
<div class="scale">
<div class="scaletick">
01/01/2000
</div>
<div class="scaletick">
02/01/2000
</div>
<div class="scaletick">
03/01/2000
</div>
<div class="scaletick">
04/01/2000
</div>
<div class="scaletick">
05/01/2000
</div>
<div class="scaletick">
06/01/2000
</div>
<div class="scaletick">
07/01/2000
</div>
<div class="scaletick">
08/01/2000
</div>
<div class="scaletick">
09/01/2000
</div>
<div class="scaletick">
10/01/2000
</div>
</div>
<div class="tasks">
<div class="taskcard taskcard1">
Task 1
</div>
<div class="taskcard taskcard2">
Task 2
</div>
<div class="taskcard taskcard3">
Task 3
</div>
<div class="taskcard taskcard4">
Task 4
</div>
<div class="taskcard taskcard5">
Task 5
</div>
<div class="taskcard taskcard5">
Task 6
</div>
<div class="taskcard taskcard7">
Task 7
</div>
<div class="taskcard taskcard8">
Task 8
</div>
<div class="taskcard taskcard9">
Task 9
</div>
<div class="taskcard taskcard10">
Task 10
</div>
</div>
</div>
</div>
</div>
How can I get the necessary behaviour?

List item will go second column automatic and container space will also increase [duplicate]

This question already has answers here:
When flexbox items wrap in column mode, container does not grow its width
(9 answers)
Closed 4 years ago.
I'm trying to build navigation which will be vertical. Navigation's outer width will be fixed and when the item will be increased then other items will go to the next column.
I tried it with flexbox and added flex-wrap: wrap; in the container. But cant design this.
I tried with these codes.
.container {
display: flex;
flex-direction: column;
height: 320px;
width: 80px;
flex-wrap: wrap;
background: red;
padding: 10px
}
.item {
padding: 20px 30px;
background: #efefef;
display: inline-block;
margin: 0 5px 5px 0;
width: 20px
}
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
</div>
Instead of width: 80px; give width: auto or do not provide width at all. When the number of items increases touches to the bottom of the container it will be added to the next column.
You do not have control over the container with here. You should make it flexible with auto width.
Learn more here.
.container {
display: flex;
flex-direction: column;
height: 320px;
flex-wrap: wrap;
background: red;
padding: 10px;
width: auto;
}
.item {
padding: 20px 30px;
background: #efefef;
display: block;
margin: 0 5px 5px 0;
width: 20px;
}
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
</div>

How to design a layout like this: one box on top and two bottom covering the whole page

I want 3 section one cover half part of the screen to show image slider and in half part, there is two section right now that part I'm done but now I want to add half part of the screen on top but it does not show image slider section, please help me.
right now my code:
<head runat="server">
<title></title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style>
body {
font-family: Arial;
color: white;
}
.split {
height: 100%;
width: 50%;
position: fixed;
z-index: 1;
top: 0;
overflow-x: hidden;
padding-top: 20px;
}
.left {
left: 0;
background-color: #ff6a00;
}
.right {
right: 0;
background-color: #ffd800;
}
.centered {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
text-align: center;
}
.centered img {
width: 150px;
border-radius: 50%;
}
</style>
</head>
<body>
<form id="form1" runat="server">
<div class="split left">
<div class="centered">
<h2>Blood Donor</h2>
<p>Go To Registration</p>
</div>
</div>
<div class="split right">
<div class="centered">
<h2>Blood Seeker</h2>
<p>Go To Registration</p>
</div>
</div>
</form>
</body>
please help me,
Thank You for your time.
He's a simple layout using CSS Grid (the 2D version of Flexbox):
.main {
display: inline-grid;
height: 200px;
width: 400px;
grid-template-rows: 50% 50%;
border: green solid 2px;
}
.main .level1 {
border: blue solid 2px;
display: flex;
}
.main .level1 .level2 {
border: red solid 2px;
flex-basis: 50%;
}
<div class="main">
<div class="level1"></div>
<div class="level1">
<div class="level2"></div>
<div class="level2"></div>
</div>
</div>
If you are happy using grid then is quite easy. You just need to setup a grid which with two columns and two rows.
Here is a link to a codepen, there are some other styles to make it a little easier to see what is going on but you only need to pay attention to the grid css attributes.
.container {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: repeat(2, 1fr);
height: 50vh;
}
.container>div {
display: flex;
justify-content: center;
align-items: center;
}
.image-slider {
background: magenta;
grid-column: span 2;
}
.page-link-1 {
background: red;
}
.page-link-2 {
background: green
}
<div class="container">
<div class="image-slider">Image Slider</div>
<div class="page-link-1">Page Link 1</div>
<div class="page-link-2">Page Link 2</div>
</div>
https://codepen.io/tmcnicol/pen/PdoLpm/
My implementation with flex:
body,
html {
height: 100%;
}
.wrap {
display: flex;
height: 100%;
flex-direction: column;
}
.slider {
border: 2px solid red;
flex: 1;
display: flex;
align-items: center;
justify-content: center;
}
.bottom-wrap {
display: flex;
flex: 1;
}
.link {
border: 2px solid red;
flex: 1;
display: flex;
align-items: center;
justify-content: center;
}
<div class="wrap">
<div class="slider">Image slider</div>
<div class="bottom-wrap">
<div class="link">Page Link</div>
<div class="link">Page Link</div>
</div>
</div>
Working codepen

Categories