CSS - How to make a dynamic bootstrap list scrollable - css

I have this code in my vue app
<form class="d-flex me-auto" id="searchBar">
<div class="input-group">
<input class="form-control" type="text" placeholder="Cerca professionista" #keyup="search" aria-label="Search" v-model="searchInput">
<button class="btn btn-outline-success" #click.prevent="search">
<i class="fa-solid fa-search"></i>
</button>
</div>
</form>
<div class="list-group" v-if="searchResults.length > 0" id="searchResultsList">
<a href="#" class="list-group-item list-group-item-action" v-for="(result, index) in searchResults" :key="index" id="searchResult" #click.prevent="showUserProfile(result.username)">
<div class="d-flex w-100 justify-content-between">
<p class="ps-2 me-auto mb-1">{{ result.name }} {{ result.surname }}</p>
<!-- <img :src="result.propicUrl" id="searchResultThumbnail"> -->
</div>
<small class="ps-2 me-auto">{{ result.category }}</small>
</a>
</div>
I will have a list that will contain the results of a search, since there are a lot of results, how I can make it scrollable? At the moment I have added this css rules but not working
<style lang="scss">
#menu {
height: 75px;
.navbar-brand {
padding-top: 0;
#logo {
width: 60px;
height: 60px;
}
}
#searchBar {
width: 420px;
}
#searchResultsList {
position: absolute;
top: 3.8em;
left: 5.4em;
width: 420px;
overflow-y: scroll;
#searchResult {
overflow-y: scroll;
#searchResultThumbnail {
height: 40px;
width: 40px;
border-radius: 50%;
}
}
}
}
</style>

You need to set either height or max-height to a value that results in a concrete size (e.g: 40vw, 200px, 20pt) for overflow-y: auto | scroll to have any effect.
Without setting the (max-)height, the element will grow to match the height of its children and will never display an active scrollbar.
Side note: considering the element has position: absolute, height: 100% will likely delegate the height request to the closest positioned ancestor but, again, you do need a positioned ancestor with a concrete height for overflow-y: auto | scroll to work.
Generic example:
Vue.createApp().mount('#app')
#app {
max-height: 100px;
overflow-y: auto;
border: 1px solid red;
}
<script src="https://unpkg.com/vue#next/dist/vue.global.prod.js"></script>
<div id="app">
<div v-for="n in 20">test</div>
</div>
Playground:
const { createApp, reactive, toRefs } = Vue;
createApp({
setup: () => ({
...toRefs(reactive({
setHeight: false,
setMaxHeight: true,
listLength: 20
}))
})
}).mount('#app')
#app {
display: flex;
}
#app>* {
flex: 0 0 50%;
}
.scroller {
overflow-y: auto;
border: 1px solid red;
}
.controls {
padding: 0 1rem;
display: flex;
flex-direction: column;
}
* {
box-sizing: border-box;
}
<script src="https://unpkg.com/vue#next/dist/vue.global.prod.js"></script>
<div id="app">
<div class="scroller" :style="{ height: setHeight ? '100px' : '', maxHeight: setMaxHeight ? '100px': ''}">
<div v-for="n in listLength">test</div>
</div>
<div class="controls">
<div>
Items: <input type="number" v-model="listLength">
</div>
<label>
<input v-model="setHeight" type="checkbox">
Set height
</label>
<label>
<input v-model="setMaxHeight" type="checkbox">
Set max height
</label>
</div>
</div>
The difference between setting height and max-height is that with height the element will have the specified height even when it doesn't have enough content to fill it, while with max-height, when you don't have enough content, the element will shrink all the way down to 0 (unless something else gives it a soft min-height: e.g: a flex container).

Related

Two child components in parent div (flex row) always at the same height in angular 10

disclaimer: sorry if my answer is somwhere in stackoverflow... Did not find and starting being a little frustrating...
I'm working with Angular 10 and in my app.component.html, have this snippet :
<div class="chats">
<app-friend-chat *ngFor="let friend of friends" [inputFriend]="friend" (close)="closeChat($event)">
</app-friend-chat>
<app-friend-list (friend)="openChat($event)"></app-friend-list>
</div>
The component app-friend-chat is dynamic and at the started time of the site, there is no instances of it so only app-friend-list is display.
Here is the css of app.component.css :
app-friend-chat{
position: relative;
margin: 0 !important;
width: 50vh;
}
.chats{
position: absolute;
bottom: 0;
right: 5px;
z-index: 9999;
display: flex;
flex-direction: row;
}
The thing is app-friend-list's height is moving up to creation of a new app-chat-friend's instance.
When closing all app-chat-friend's instances, app-friend-list get height back to its first value.
I want my app-friend-list keep its height.
Here is app-friench-chat'html :
<div *ngIf="friend">
<div class="chatHead" fxLayout="row" fxLayoutGap="5px">
<p class="friend">{{ friend.name }}</p>
<span fxFlex="auto" (click)="minimize()"></span>
<p class="close" (click)="closeChat(friend.name)">X</p>
</div>
<div *ngIf="!mini">
<div id="messages-box">
<div *ngFor="let message of messages" class="message">
<div [ngClass]="classForParagraphe(message)" class="paragraphe"
[innerHTML]="sanitizer.bypassSecurityTrustHtml(message.message)">
</div>
<div *ngIf="user.name === message.user" class="trash">
<span class="far fa-trash-alt" (click)="deleteMessage(message)"></span>
</div>
</div>
</div>
<emoji-mart class="emoji-mart" *ngIf="isEmojiPickerVisible" (emojiSelect)="addEmoji($event)"></emoji-mart>
<div fxLayout="row" fxLayoutGap="15px">
<div class="container">
<input [(ngModel)]="message" type="text" #input (keyup)="enter($event)" />
<button (click)="isEmojiPickerVisible = !isEmojiPickerVisible;">😀</button>
</div>
<button (click)="sendMessage()">
<svg width="20px" height="20px" viewBox="0 0 24 24">
<path
d="M16.6915026,12.4744748 L3.50612381,13.2599618 C3.19218622,13.2599618 3.03521743,13.4170592 3.03521743,13.5741566 L1.15159189,20.0151496 C0.8376543,20.8006365 0.99,21.89 1.77946707,22.52 C2.41,22.99 3.50612381,23.1 4.13399899,22.8429026 L21.714504,14.0454487 C22.6563168,13.5741566 23.1272231,12.6315722 22.9702544,11.6889879 C22.8132856,11.0605983 22.3423792,10.4322088 21.714504,10.118014 L4.13399899,1.16346272 C3.34915502,0.9 2.40734225,1.00636533 1.77946707,1.4776575 C0.994623095,2.10604706 0.8376543,3.0486314 1.15159189,3.99121575 L3.03521743,10.4322088 C3.03521743,10.5893061 3.34915502,10.7464035 3.50612381,10.7464035 L16.6915026,11.5318905 C16.6915026,11.5318905 17.1624089,11.5318905 17.1624089,12.0031827 C17.1624089,12.4744748 16.6915026,12.4744748 16.6915026,12.4744748 Z">
</path>
</svg>
</button>
</div>
</div>
</div>
And css :
.chatHead {
background: rgb(210, 206, 206);
border-radius: 10px;
height: 5vh;
}
#messages-box {
height: 45vh;
background-color: white;
padding-left: 0;
overflow-y: scroll;
}
app-friend-list'html:
<div *ngIf="user && user.name !== undefined">
<h6 (click)="showList()">Discussions</h6>
<div class="list" *ngIf="show">
<ul *ngFor="let ami of user.amis">
<li (click)="addChat(ami)">{{ ami }}</li>
</ul>
</div>
</div>
app-friend-list'css:
h6{
padding: 10px;
border: solid 1px black;
height: 5.5vh;
}
ul {
padding-right: 20px;
}
li {
list-style: none;
cursor: pointer;
}
I give you only relevant code (according to me).
The other probleme I can't get ride of is that when clicking on chatHead of app-friend-chat for minimize, the component get same size of app-friend-list and so let empty space at the bottom which is very dirty (should get only size of head part)
Feel free to ask me any code I forgot to give you.

How can i do my <mat-card> doesn't expand when messages are displayed in Angular 9

I have my <mat-card> that has one form for the login of my page, the problem is when the error messages are displayed they change the size of the <mat-card> vertically and i need it to stay in the same size.
How can i do that?
Below i will let my html file , the sass file of the error messages and pictures of what I have
html file
<div class="bg">
<div class="main-div color ">
<mat-card class="z-depth center col-sm-4 " flex="50" >
<mat-radio-group aria-label="Select an option" [(ngModel)]="radio_btn">
<mat-radio-button [value]="true" >User</mat-radio-button>
<mat-radio-button [value]="false">Admin</mat-radio-button>
</mat-radio-group>
<div class="row justify-content-center " *ngIf="radio_btn==true;else form2">
<form class="example-form " [formGroup]="loginForm" (ngSubmit)="sendUser()">
<mat-form-field class="example-full-width ">
<input matInput formControlName="Identifier" placeholder="Identifier" >
</mat-form-field><br>
<div class=" alert-danger space" *ngIf="identifier.invalid && (identifier.dirty || identifier.touched)">
<div class="container-error-message " *ngIf="identifier.errors.required">
Identifier required
</div>
<div class="container-error-message" *ngIf="identifier.errors.minlength">
Identifier must be at least 7 characters long.
</div>
</div>
<br>
<mat-form-field class="example-full-width">
<input matInput formControlName="Password" placeholder="Password" type="password" >
</mat-form-field><br>
<div class="alert-danger space" *ngIf="password.invalid && (password.dirty || password.touched)">
<div class="container-error-message" *ngIf="password.errors.required">
Password required
</div>
<div class="container-error-message" *ngIf="password.errors.minlength">
Password must be at least 5 characters long.
</div>
</div>
<br>
<button mat-raised-button [class.black]="!loginForm.invalid" [disabled]="loginForm.invalid" type="submit">Sign in</button>
</form>
</div>
<ng-template #form2>
<app-home-admin></app-home-admin>
</ng-template>
</mat-card>
</div>
</div>
SASS file
#import './../../variables_scss/variables.scss';
example-icon {
padding: 0 14px;
}
.example-spacer {
flex: 1 1 auto;
}
.down{
overflow-y: auto;
.colour{
//background: #141519;
background: $orange-bg;
.icons {
color: $black;
}
}
}
.container{
align-items: center;
}
.main-div{
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
.center{
width: 75%;
margin: 10px auto;
.mat-radio-button ~ .mat-radio-button {
margin-left: 16px;
}
button {
display: block;
width: 100%;
margin: 2px;
text-align: center;
color: $orange !important;
border-radius: 8px;
}
}
}
.bg{
background: $black;
background: linear-gradient(to right, $dark_black,$light_black );
}
.behind{
z-index: 10;
}
.black {
background-color:$black !important;
}
.space{
margin: $margin-errors;
text-align: $text-align-center;
width: $width-erros;
border: 1px solid;
}
* scss_variables*
$dark_black: #1b1b1b;
$light_black: #424242;
$black: #141519;
$margin-left: auto;
$orange: #fc6407;
$colour_button :$black;
$orange-bg: linear-gradient(to right, #c43e00, #ff6f00);
$margin-errors: 0 auto;
$text-align-center: center;
$width-erros: 180px;
I am not able to replicate your issue with the code given by you. But i would suggest you to provide a constant height to mat-card which is sufficient to enclose all the items. Like i am taking 400px below:
mat-card {
height: 400px;
}
This is how i solve it
Adding this to the space class
max-height: 0px ;
margin-top: 0px !important;
Adding this to the center class
height: 290px;
You can add maximum height and minimum hight of card as same like this in your CSS file , it's worked for me, if you done like this then if the content size is height,automatically scroll will be apply without any size correction
.mat-card{
min-height: 230px ;
max-height: 230px ;
}

Fill the page entirely with background color

How can I extend the color green up to bottom? And how can I move the CRUD in left too
So as you can see it can't fill the page entirely.
Here's my code in VueJS
<template>
<div class="container-fluid">
<h1>CRUD</h1>
<div class="my-form col-xs-1">
<b-card class="box">
<b-form-group id="input-group-1">
<b-form-input
id="input-1"
required
placeholder="Username"
></b-form-input>
</b-form-group>
<b-form-group id="input-group-2">
<b-form-input
id="input-2"
type="password"
required
placeholder="Password"
></b-form-input>
</b-form-group>
<div class="btn">
<b-button variant="primary" >Login</b-button>
<b-button variant="success" #click="$router.push('/register')">Register</b-button>
</div>
</b-card>
</div>
</div>
</template>
<script>
export default {}
</script>
<style scoped>
.container-fluid {
background-color: green;
height: 100%;
}
.my-form {
display: block;
margin-top: 120px;
margin-bottom: 120px;
}
.box {
padding: 10px;
margin-bottom: 20px;
}
.btn {
margin: 5px;
}
</style>
What is my mistake with this? I tried using flex a while ago but didn't understand why it always fits the content to itself.
By the way sorry for my bad English.
THanks
just write in your body tag it will solve your problem
bgcolor="green"
Use CSS to get the background color changed, and ensure the body (document) is at least 100% of the viewport height :
body {
background-color: green;
min-height: 100vh;
}
To align "CRUD" to the left, use the Bootstrap utility class "text-left":
<h1 class="text-left">CRUD</h1>
https://getbootstrap.com/docs/4.3/utilities/text/
https://bootstrap-vue.js.org/docs/reference/utility-classes

summernote dropdown-menu overflow

I have a 2 columns layout inside 2 divs with different margins set, on the left column I have a bootstrap datetimepicker and summernote.
As you can see the datetimepicker dialog overflows outside the internal div, how can I achieve the same with summernote's dropdowns? Is it possible?
Here's my playground with the issue: https://jsfiddle.net/SycoLTH/2j0ykbgf/
<style>
form {
height: 100%;
width: 100%;
}
#out-container {
background-color: #000000;
margin: 0;
padding: 0;
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
display: flex;
}
#in-container {
background-color: #FFFFFF;
width: 100%;
height: 100%;
max-height: 80%;
max-width: 70%;
margin: auto;
padding: 3%;
}
#column-left,
#column-right {
height: 100%;
width: 50%;
overflow: auto;
}
</style>
<script type="text/javascript">
$(".datetimepicker").datetimepicker({
showClear: true,
showTodayButton: true
});
$(".summernote").summernote({
theme: "simplex",
disableDragAndDrop: true,
shortcuts: false,
toolbar: [
["style", ["bold", "italic", "underline", "clear"]],
["misc", ["undo", "redo"]],
["font", ["strikethrough", "superscript", "subscript"]],
["fontsize", ["fontsize"]],
["color", ["color"]],
["para", ["ul", "ol", "paragraph"]],
["insert", ["picture", "link", "video", "table", "hr"]],
["height", ["height"]]
]
});
</script>
<div id="out-container">
<div id="in-container">
<form>
<div id="column-left" class="pull-left">
Some text
<br> Some text
<br> Some text
<br> Some text
<br> Some text
<br> Some text
<br>
</div>
<div id="column-right" class="pull-left">
Date:
<br>
<input type="text" class="datetimepicker form-control" />
<br>
<br> Text:
<br>
<textarea class="summernote"></textarea>
</div>
</form>
</div>
</div>
position: absolute objects are cropped by the bound of its nearest position: relative object. In this case, the easiest way to show summernote popovers over the boundary, try to set the right column as below.
#column-right {
overflow:visible;
}
Ref: http://front-back.com/how-to-make-absolute-positioned-elements-overlap-their-overflow-hidden-parent

How to make element fill remaining width, when sibling has variable width?

In the example below:
I want the textbox to fill all available space. The problem is the dropdown width cannot be fixed, since its elements are not static. I would like to solve this with just css (no javascript if possible).
I have tried the solutions proposed to similar questions without any luck :(
Here is the fiddle: http://jsfiddle.net/ruben_diaz/cAHb8/
Here is the html:
<div id="form_wrapper">
<form accept-charset="UTF-8" action="/some_action" method="post">
<span class="category_dropdown_container">
<select class="chosen chzn-done" name="question[category_id]" id="selQJK">
<option value="1">General</option>
<option value="2">Fruits</option>
<option value="3">Ice Creams</option>
<option value="4">Candy</option>
</select>
</span>
<span class="resizable_text_box">
<input id="question_text_box" name="question[what]" placeholder="Write a query..." type="text" />
</span>
<input name="commit" type="submit" value="Ask!" />
</form>
</div>
And here the css:
#form_wrapper {
border: 1px solid blue;
width: 600px;
padding: 5px;
}
form {
display: inline-block;
width: 100%;
}
.category_dropdown_container {
}
.resizable_text_box {
border: 1px solid red;
}
input[type="text"] {
}
input[type="submit"] {
background-color: lightblue;
width: 80px;
float: right;
}
Updated demo (tested fine in IE7/8/9/10, Firefox, Chrome, Safari)
Float the left and right elements.
In the HTML source code, put both of the floated elements first (this is the most important part).
Give the middle element overflow: hidden; and an implict width of 100%.
Give the text box in the middle element a width of 100%.
.category_dropdown_container {
float: left;
}
input[type="submit"] {
float: right;
...
}
.resizable_text_box {
padding: 0 15px 0 10px;
overflow: hidden;
}
.resizable_text_box input {
width: 100%;
}
<div class="category_dropdown_container">
<select class="chosen chzn-done" name="question[category_id]" id="selQJK">
...
</select>
</div>
<input name="commit" type="submit" value="Ask!" />
<div class="resizable_text_box">
<input id="question_text_box" name="question[what]"
placeholder="Write a query..." type="text" />
</div>
The relatively recent 'flex' display css property solves this problem for you:
All you need to do is change form's display to inline-flex, give .resizable_text_box flex-grow: 100; and give #question_text_box width: 100%
Full example from the OP:
<style>
#form_wrapper {
border: 1px solid blue;
width: 600px;
padding: 5px;
}
form {
display: inline-flex;
width: 100%;
}
.category_dropdown_container {
}
.resizable_text_box {
border: 1px solid red;
flex-grow: 100;
}
#question_text_box {
width: 100%
}
input[type="text"] {
}
input[type="submit"] {
background-color: lightblue;
width: 80px;
float: right;
}
</style>
<div id="form_wrapper">
<form accept-charset="UTF-8" action="/some_action" method="post">
<span class="category_dropdown_container">
<select class="chosen chzn-done" name="question[category_id]" id="selQJK">
<option value="1">Options</option>
</select>
</span>
<span class="resizable_text_box">
<input id="question_text_box" name="question[what]" placeholder="Write a query..." type="text" />
</span>
<input name="commit" type="submit" value="Ask!" />
</form>
</div>
Flex-box lets you do what you wanted to do with css for 15 years - its finally here! More info: https://css-tricks.com/snippets/css/a-guide-to-flexbox/
Change some of those <span> elements to <div> elements; then float:left the division around your dropdown; then give the one of the right an overflow:hidden and the input element inside it a width:100%;.
Here's an example. Here it is again with a bigger drop down.
Except that screws up the submit button. So give the #form_wrapper non-static positioning (position:relative) and position the submit button absolutely. See this fiddle and this one.

Resources