How to keep block level when use position fixed? - css

When using position: fixed, the browser will remove the original place the layout thing have. How to prevent it?
In my case, the actual fixed position of a search appbar act as
Expecting act as.
Simulating css code.
.search-appbar-container {
position: fixed;
display: flex;
flex-direction: row;
align-items: center;
width: 100%;
height: 48px;
}
.lef-arrow-icon-container`
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
width: 60px;
`;
.search-textfiled-container`
display: flex;
flex: 1;
flex-direction: row;
align-items: center;
`;
.add-icon-container`
display: flex;
flex-direction: row;
align-items: center;
`;
.search-history-container {
display: flex;
flex-direction: column;
justify-content: center;
width: 100%;
margin-top: 5px;
}
.history-toggle-button`
position: relative;
width: 100%;
height: 48px;
background-color: transparent;
-webkit-box-sizing: border-box;
box-sizing: border-box;
border: none;
outline: none;
-webkit-appearance: none;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
-webkit-tap-highlight-color: transparent;
`;
.history-icon-container`
position: absolute;
top: 11.5px;
left: 0;
width: 60px;
`;
.history-text-container`
position: absolute;
top: 11.5px;
left: 60px;
display: flex;
flex-direction: row;
align-items: center;
`;
Simulating html code.
<div>
<div class="search-appbar-container">
<div class="left-arrow-container>
...
</div>
<div class="search-textfield-container>
...
</div>
<div class="add-icon-container>
...
</div>
</div>
<div class="search-history-div">
<button class="history-toggle-button">
<div class="history-icon-container>
...
</div>
<div class="history-text-container>
...
</div>
</button>
</div>
</div>
EDIT
Have checkout all of my code, now I can find why this happened.
If the position of .search-appbar-container is static, the absolute position of history-icon-container and history-text-container are related the relative position of history-toggle-button, otherwise they are all related fixed position of search-appear-container.

you can set margin-top or padding-top to .search-history-div or set .search-history-div{position: fixed;top: 48px}

After searching and trying by myself, I have come out with a idea. If you want to keep fixed div with a block level, the proper way is to wrapper the same size parent div over it. Reflecting to my case, add the same width and height wrapper div upper search-appbar-container
.search-appbar-container-wrapper {
width: 100%;
height: 48px;
}
.search-appbar-container {
position: fixed;
...
width: 100%;
height: 48px;
}
...
<div class="search-appear-container-wrapper">
<div class="search-appbar-container">
...
</div>
</div>
...

Related

Vue-Router Flexbox not scrolling properly (or at all)

I have a component with a router-view inside it that can display a flexbox. I've tried several different solutions to flex-boxes not scrolling properly and they all either result in no scrolling, or scrolling, but it doesn't quite reach the bottom (the last element in the v-for ends up getting cut off.)
Here is the template and relevant styles for the router view
<template>
<div class="modal" ref="modal">
<div class="modalcontent" ref="content">
<p class="goback" #click="closeAnimation" ref="goback">←</p>
<div class="title">
<h1>Questions & Answers</h1>
</div>
<div class="routerview">
<router-view :posts="posts" v-slot="{ Component }">
<transition name="slide-in" mode="out-in">
<component :is="Component" />
</transition>
</router-view>
</div>
</div>
</div>
</template>
<style>
.routerview {
position: relative;
width: 80%;
margin: auto;
overflow-y: scroll;
left: 0;
right: 0;
outline: 10px red;
}
</style>
and for the flexbox:
<template>
<div class="container">
<div class="flex-container" ref="flexcontainer">
<div class="question" v-for="post in posts" :key="post._id" #click="this.$router.push(`/forum/question/${post._id}`)">
<h1 class="qTitle">{{ post.title }}</h1>
<p class="qReplyAmt">{{ post.replies.length }} repl<span v-if="!plural(post.replies.length)">y</span><span v-else>ies</span></p>
</div>
</div>
<p>You've reached the end</p>
</div>
</template>
<style scoped>
.question {
width: 98%;
height: fit-content;
min-height: 0;
background-color: whitesmoke;
border-radius: 10px;
padding: 10px 10px 2px 15px;
cursor: pointer;
transition: all 200ms ease-out;
}
.question:hover {
background-color: rgb(255, 107, 107);
color: white;
}
.qTitle {
display: block;
}
.qReplyAmt {
position: relative;
top: -5px;
}
.flex-container {
display: flex;
align-items: center;
flex-direction: column-reverse;
width: 100%;
gap: 15px;
flex: 1;
}
</style>
I've tried:
setting a height on .container, .routerview, .flex-container
setting overflow-y to auto & scroll on .container, .routerview, .flex-container
and a bunch of other answers i've found on how to fix flexboxes not scrolling
I fixed the issue. Here is the updated styles:
.flex-container {
display: flex;
align-items: center;
justify-content: space-between;
flex-direction: column-reverse;
width: 100%;
gap: 15px;
flex: 1;
margin-top: auto;
margin-bottom: 125px;
}
.container {
overflow-y: scroll;
height: 100vh;
}
I added the .container styles to make it actually scroll and added margin-bottom: 125px; to fix the issue with the last item being cut off.

i need to change to layout of the buttons and the counter

counter.js
import "./Counter.css";
const Counter = (props) => {
return (
<div className="counter">
<h1>{`Counter ${props.count}`}</h1>
<div className="counter__buttons">
<button onClick={props.incrementCounter}>Increment</button>
<button onClick={props.decrementCounter}>Decrement</button>
</div>
</div>
);
};
Counter.css
.counter {
display: flex;
color: white;
align-items: center;
width: 100%;
height: 100%;
}
.counter > .counter__buttons > button {
color: black;
background-color: grey;
margin: 10px;
padding: 30px;
border: 0;
border-radius: 10px;
}
i want to move the buttons below counter and place the counter and buttons in the center of the page how to change it , display : flex in counter should not be removed
Would something like this work? You can set the flex-direction of a wrapping div to column and set the second div (in your case your buttons) back to flex-direction: row and finally just center it with margin: 0 auto.
<div id="wrap">
<div id="one">1</div>
<div id="two">2
<div id="three">3</div>
<div id="four">4</div>
</div>
</div>
#wrap {
display: flex;
flex-direction: column;
}
#two {
display: flex;
flex-direction: row;
margin: 0 auto;
}
Do you want something like this?
.page {
background: black;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100vh;
}
.counter {
display: flex;
flex-direction: column; /* add this */
color: white;
align-items: center;
/* width: 100%;*/
/* height: 100%;*/
}
.counter > .counter__buttons > button {
color: black;
background-color: grey;
margin: 10px;
padding: 30px;
border: 0;
border-radius: 10px;
}
<div class="page">
<div class="counter">
<h1>Counter 5</h1>
<div class="counter__buttons">
<button onClick={props.incrementCounter}>Increment</button>
<button onClick={props.decrementCounter}>Decrement</button>
</div>
</div>
</div>
If so, you can make your whole page a flex container and use justify-content and align-items just like you did it for the .counter.
(I did HTML instead of JSX so I could add the snippet easier... don't forget to make changes in your own code)

How can I achieve a reversed stack of elements in a scrollable container in Google Chrome?

I have achieved the effect I desire with the code below, but it only seems to work in Firefox and Edge. In Chrome, the elements are stacked as desired, but there is no horizontal scroll bar so the right most items are hidden and inaccessible to the user.
As you can see, the header and footer stay in place and the my-app element is the only part that is scrollable. The items on the left appear above the ones to the right and the items all the way to the right are available through scrolling.
body {
margin: 0;
height: 100vh;
}
my-app {
display: flex;
height: 100vh;
flex-direction: column;
}
header, footer {
height: 25px;
background-color: black;
color:white;
}
main {
display: flex;
flex-direction: row-reverse;
flex-grow: 1;
justify-content: flex-end;
margin: 0;
overflow-x: auto;
width: 100vw;
}
.card {
--card-height: 200px;
--card-width: 250px;
align-items: center;
background: linear-gradient(rgba(179, 156, 95, 1), rgba(150, 117, 24, 1));
border-radius: 5px;
box-shadow: 1.5rem 0 2rem #222;
color: #000;
display: flex;
flex-direction: column;
height: var(--card-height);
justify-content: center;
min-width: var(--card-width);
position: relative;
text-align: center;
transition: all .15s ease-in-out;
transition: margin .3s ease-in-out;
width: var(--card-width);
}
.card:not(:last-of-type) {
margin-left: calc(var(--card-width) * -.5);
}
.card:hover:not(:last-of-type) {
margin-left: 0;
}
<my-app>
<header>Header</header>
<main>
<div class="card">1</div>
<div class="card">2</div>
<div class="card">3</div>
<div class="card">4</div>
<div class="card">5</div>
<div class="card">6</div>
<div class="card">7</div>
<div class="card">8</div>
<div class="card">9</div>
<div class="card">10</div>
<div class="card">11</div>
<div class="card">12</div>
<div class="card">13</div>
<div class="card">14</div>
<div class="card">15</div>
</main>
<footer>Footer</footer>
</my-app>
If I change the css applied to main to:
main {
...
flex-direction: row;
...
justify-content: flex-start;
...
}
Then the scroll bar appears, but the items aren't stacked correctly(the ones on the right overlay the ones on the left).
If I go one step further and add direction: rtl; to the main style as well, the layout works as expected, but the default scroll position is all the way to the right of the screen(which makes sense). I could probably keep this and add some javascript to change the scroll location on page load, but that all seems quite hacky. Is there a better way to achieve the layout I'm looking for that will work in Chrome, Firefox and Edge?
Looks like an additional wrapper solves your problem:
body {
margin: 0;
height: 100vh;
}
my-app {
display: flex;
height: 100vh;
flex-direction: column;
}
header,
footer {
height: 25px;
background-color: black;
color: white;
}
main {
flex-grow: 1;
margin: 0;
overflow-x: auto;
width: 100vw;
}
.wrapper {
display: flex;
flex-direction: row-reverse;
justify-content: flex-end;
}
.card {
--card-height: 200px;
--card-width: 250px;
align-items: center;
background: linear-gradient(rgba(179, 156, 95, 1), rgba(150, 117, 24, 1));
border-radius: 5px;
box-shadow: 1.5rem 0 2rem #222;
color: #000;
display: flex;
flex-direction: column;
height: var(--card-height);
justify-content: center;
min-width: var(--card-width);
position: relative;
text-align: center;
transition: all .15s ease-in-out;
transition: margin .3s ease-in-out;
width: var(--card-width);
}
.card:not(:last-of-type) {
margin-left: calc(var(--card-width) * -.5);
}
.card:hover:not(:last-of-type) {
margin-left: 0;
}
<my-app>
<header>Header</header>
<main>
<div class="wrapper">
<div class="card">1</div>
<div class="card">2</div>
<div class="card">3</div>
<div class="card">4</div>
<div class="card">5</div>
<div class="card">6</div>
<div class="card">7</div>
<div class="card">8</div>
<div class="card">9</div>
<div class="card">10</div>
<div class="card">11</div>
<div class="card">12</div>
<div class="card">13</div>
<div class="card">14</div>
<div class="card">15</div>
</div>
</main>
<footer>Footer</footer>
</my-app>

Why flexbox not working responsive design with flex-direction?

i have doing my portfolio but i'm not good with CSS.
I'm using the Flexbox to do the design desktop and mobile but it not working...
It is like this, as i want, using flex-direction: column,:
Code of the div parent:
display: flex;
justify-content:center;
align-items:center;
background-color:#C4C4C4;
min-height: 100vh;
flex-direction: column;
But when i put in responsive, it stay like this:
The elements outside of div parent..
The code is the same, only changes the background-color.
background-color: red;
width:800px;
height:650px;
margin: 30px;
It not stay corrects.
If i dont use the flex-direction: column, it stay like this:
Someone why?
Your main issue was missing max-width: 100%; in the children so the width:800px would not overflow the container parent, take a look at the snippet
section {
display: flex;
justify-content: center;
align-items: center;
background-color: #C4C4C4;
min-height: 100vh;
padding: 15px 30px;
box-sizing: border-box;
}
#media(max-width:800px) {
section {
flex-direction: column;
}
}
div {
max-width: 100%;
width: 800px;
height: 650px;
margin: 15px
}
div:first-of-type {
background-color: red;
}
div:last-of-type {
background-color: blue
}
<section>
<div>red</div>
<div>blue</div>
</section>
max-width not set the width of the children elements.
Make sure you set a width to all of your containers; it looks like you want the gray container to fill the viewport, and the blocks to be evenly distributed.
Here's a working example:
.container {
display: flex;
flex-direction: column;
justify-content: space-evenly;
align-items: center;
text-align: center;
background-color: gray;
width: 100vw;
height: 100vh;
}
.block {
background-color: #C4C4C4;
min-height: 33vh;
width: 90vw;
}
<div class="container">
<div class="block" style="background-color: red">
A
</div>
<div class="block" style="background-color: blue">
B
</div>
</div>

Breaking a line with flexbox centering?

I'm trying to vertically/horizontally center my Title with the Subtitle directly beneath it. Here was my attempt:
html, body, h1 {
margin: 0;
padding: 0;
}
html, body {
width: 100%;
height: 100%;
}
#container {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
<div id="container">
<h1>Main Title</h1>
<span>Subtitle</span>
</div>
As you can see, the subtitle is in the same line as the h1, I'm trying to get it to go beneath it. I've tried setting h1 to display: block; but that seems to not work when using display: flex on the container. Any help would be appreciated.
Set flex-direction: column on container
html, body, h1 {
margin: 0;
padding: 0;
}
html, body {
width: 100%;
height: 100%;
}
#container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100vh;
}
<div id="container">
<h1>Main Title</h1>
<span>Subtitle</span>
</div>
Setting flex-direction to column is one solution. It's already provided in another answer.
In some cases, if flex-direction: row is preferred (or a necessity), you can add flex-wrap: wrap to the container and give the first item a 100% width, which forces the second item to the next line.
body, h1 {
margin: 0;
padding: 0;
}
#container {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
flex-wrap: wrap; /* NEW */
align-content: center; /* NEW */
text-align: center; /* NEW */
}
h1 { flex: 0 0 100%; } /* NEW */
<div id="container">
<h1>Main Title</h1>
<span>Subtitle</span>
</div>

Resources