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.
Related
Hello I am making a cards type of component in React, I have a problem with styling this particular part as the flexbox items is overlapping the wrapper.
The JSX
const OtherProjects = () => {
return (
<div className='opWrapper'>
<div className="containerWrapper">
<div className="item"></div>
<div className="item"></div>
<div className="item"></div>
<div className="item"></div>
<div className="item"></div>
<div className="item"></div>
</div>
</div>
)
The CSS
.opWrapper{
width: 100%;
height: 100vh;
margin: 0 auto;
background-color: #232A4E;
}
.containerWrapper{
display: flex;
gap: 1em;
height: 100%;
justify-content: center;
align-items: center;
flex-wrap: wrap;
margin: 0 5em;
}
.item{
width: 20em;
height: 20em;
border-radius: 10px;
border: 2px black solid;
background-color: #CCF6F6;
}
It shows it like this when viewed on this dimension and other dimensions, I am not sure why the items are overlapping and now its showing the white thing
Usual browser view:
Just remove height: 100vh; from your .opWrapper selector:
.opWrapper{
width: 100%;
margin: 0 auto;
background-color: #232A4E;
}
The reason is that your are setting height to be the height of the view port.
You can find a working example here: https://codesandbox.io/s/thirsty-wind-1ci7ei?file=/src/styles.css
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)
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>
I want my two buttons, that are actually <a> tags, stick with my input, and be the same size as input. Image perfectly describes what I want to achieve.
Note that I am just starting to learn SASS and CSS. I have tried with this but no luck
NumberInput.js
<div
className="NumberInput"
data-key={dataKey}>
<div className="numberInputField">
<input
data-key={dataKey}
type="text"
name="number"
value={getValue(datakey)}
onChange={onChange(datakey)}/>
</div>
<div className="buttonsField">
<div className="row">
<ValueChangeButton/>
</div>
<div className="row">
<ValueChangeButton/>
</div>
</div>
</div>
NumberInput.scss
$inputMaxWidth: 450px;
$maxHeight: 80px;
$btnFieldMaxWidth: 150px;
.NumberInput{
max-width: $inputMaxWidth;
max-height: $maxHeight;
.numberInputField{
display: inline-block;
text-align: center;
max-width: inherit;
max-height: inherit;
}
.buttonsField{
display: inline-block;
max-width: $btnFieldMaxWidth;
max-height: $maxHeight;
.button{
width: auto;
height: auto;
}
}
}
The result I get is, buttons are contained in their respective rows, but are not the same size as input, and they are flying all around the page. Also, if I change the className of my input, and set the className of its <div> to "numberInputField", it doesn't change its width and height.
Flexbox is perfect for this:
body {
margin: 1em;
}
.NumberInput {
display: flex;
max-width:450px;
margin:auto;
}
.numberInputField {
flex: 3; /* say 3/4 of width */
display: flex;
flex-direction: column;
}
input {
padding: 1em 4em;
flex: 1;
}
.buttonsField {
flex: 1; /* say 1/4 of width */
display: flex;
flex-direction: column;
}
.row {
flex: 1; /* share width equally */
}
a {
width: 100%;
display: block;
background: rebeccapurple;
text-align:center;
text-decoration: none;
font-size: 1.5em;
color: white;
border:1px solid grey;
}
<div class="NumberInput">
<div class="numberInputField">
<input type="submit" />
</div>
<div class="buttonsField">
<div class="row">
↑
</div>
<div class="row">
↓
</div>
</div>
</div>
I cannot get my list to be full height. My code is more complicated with nested components. But I can still get this to replicate using this code. Here is a plunk. http://plnkr.co/edit/R0QgLz8cjyRHYOLf4uJW
styles.css
html, body {
min-height: 100%;
height: auto;
margin: 0;
}
app.component.css
.container {
height: 100%;
background: black;
color: white;
list.component.css
.row {
display: flex;
flex-direction: row;
}
.list {
width: 33%;
height: 100%;
flex-direction: column;
display: flex;
border-right: groove white 1px;
border-top: groove white 1px;
}
.item {
width: auto;
height: 100%;
flex-direction: column;
display: flex;
}
list.component.html
<div class="contents">
<button (click)="updateDocuments()">Update Document</button>
<div class="row">
<div class="list">
<div *ngFor="let document of documents; let i = index;">
{{i + 1}}. {{document}}
</div>
</div>
<div class="item">
this is an item
</div>
</div>
</div>
I got this to work by switching to height 100vh and also adding a overflow-y: scroll css attribute to the list and item classes.
http://plnkr.co/edit/R0QgLz8cjyRHYOLf4uJW
styles.css
html, body {
min-height: 100vh;
height: auto;
margin: 0;
}
app.component.css
.container {
height: 100vh;
background: black;
color: white;
list.component.css
.row {
display: flex;
flex-direction: row;
}
.list {
width: 33%;
height: 100vh;
flex-direction: column;
display: flex;
border-right: groove white 1px;
border-top: groove white 1px;
overflow-y: scroll;
}
.item {
width: auto;
height: 100vh;
flex-direction: column;
display: flex;
overflow-y: scroll;
}
list.component.html
<div class="contents">
<button (click)="updateDocuments()">Update Document</button>
<div class="row">
<div class="list">
<div *ngFor="let document of documents; let i = index;">
{{i + 1}}. {{document}}
</div>
</div>
<div class="item">
this is an item
</div>
</div>
</div>
try to write this css
.container{
min-height:100vh;
}
Had the same issue, and found that the best solution was:
html, body {
min-height:100vh;
height: auto;
}
and for the container:
.container{
min-height: 100vh;
}
Use position: fixed if that's acceptable:
.container {
position:fixed;
background: black;
color: white;
height: 100%;
}
Hi everyone who faced this problem
Just go to global css file, it has the comment
/* You can add global styles to this file, and also import other style files */
written in it. Add
*{margin:0; padding:0}
that's it
Somewhere in the Internet:
The reason for this issue is concealed in the way a browser interprets
the host element, which doesn’t know it’s an HTML element at all and
so the browser sets the default display value (inline) for the host
element.
So probably it's enough just to redefine again "display" property for "host" tag (add in your component code) :
host: {
display: flex; /*or whatever is fit your needs*/
}
try in your style.css
html, body {
height: 100%;
margin: 0;
}