How to deal with CSS overflow? - html

I have an overflow menu. It is very long, but has the following style:
height: 15rem;
overflow-y: auto;
Nevertheless when I click on the menu the browser window height becomes bigger as if the menu is opened in is full size (see the difference between browser scrollbar in the first and second pictures. Besides I have empty space below my page reserved for the full-size menu.
So the invisible part of the menu nevertheless takes space. How could I fix that?
Code:
<DataTable>
<TableContainer>
<TableToolbar>
<TableToolbarContent>
<TableToolbarSearch/>
<TableToolbarMenu>
<div style={ {display: displayMenu ? "block" : "none", height: "7.5rem", width: "230px", overflowY: "auto"}}>
{filterItems.map(e => { return (
<TableToolbarAction // onClick={ ()=> setItemClicked({...e, defaultChecked: false})} onChange = {() => { setDisplayMenu(true); if(headers.map(el => el.key).includes(e.key)) { setHeaders(headers.filter(el => el.key !== e.key)); } else { setHeaders([ ...headers, { key: e.key, header:
e.header } ]) } }} hasDivider = {true} >
<Checkbox defaultChecked={ true} id={ e.key} labelText={ e.header}/>
</TableToolbarAction>
) })}
</div>
</TableToolbarMenu>
</TableToolbarContent>
</TableToolbar>
</DataTable>

Use overflow: scroll; to give a scrollbar or use overflow: hidden; to hide the overflow.

Related

onHover effect on ReactMapGL not scaling properly

Currently I'm trying to replicate this hover effect of this website on my map component: http://www.francoisrisoud.com/projects where basically when you hover over a dot, it brings up a full screen image and when you click on it, it'll take you to a particular page. Currently this is my React and CSS code:
export default function Map({posts}) {
const [viewport, setViewport] = useState({
latitude: 36.592206968562685,
longitude: 3.332469343750031,
width:"100%",
height:"100vh",
zoom: 1.3,
});
const [selectedProperty, setSelectedProperty] = useState(null)
return (
<div>
<ReactMapGL {...viewport} mapboxApiAccessToken="//myAPIkey"
mapStyle="mapbox://styles/jay/cks5xkaa892cp17o5hyxcuu0z"
onViewportChange={viewport => {
setViewport(viewport);
}}>
{
posts &&
posts.map((maps) => (
<Marker key={maps.id} latitude={maps.Latitude} longitude={maps.Longitude}>
{/* <div>{maps.Title}</div> */}
<button className="marker-btn" onClick={e => {
e.preventDefault();
setSelectedProperty(maps);
}}>
<img src="placeholder.svg"/>
</button>
</Marker>
))}
{selectedProperty ? (
<Popup latitude={selectedProperty.Latitude} longitude={selectedProperty.Longitude}
onClose={() => {setSelectedProperty(null);}}>
<h1>{selectedProperty.Title}</h1>
</Popup>) : null}
</ReactMapGL>
</div>
);
}
CSS:
.marker-btn{
background: none;
border: none;
cursor: pointer;
}
.marker-btn :hover{
background: #000;
width: 100vw;
height: 100vh;
border: none;
cursor: pointer;
}
.marker-btn img{
width: 20px;
height: 20px;
}
But when I hover over the Marker in my map this is the result I get:
I want it so that it covers my whole map and not just start from the point where I'm hovering. Additionally, if I hover out of it I want it to go away but when I drag my cursor towards the big popup, it doesnt go away.
There are a lot of ways to do it. Here is mine:
Replace onClick prop and hover pseudo-class for the button inside the Marker component with onMouseEnter prop.
Create your own Popup that has a full height and width of the parent component.
Hide the Map component (by setting the width and height of viewport into 0%) and show the custom Popup component when the mouse enters the button and vice versa.
Here is the working code https://codesandbox.io/s/full-popup-mapbox-stackoverflow-36oi0?file=/src/App.js
Note: you have to attach your own Mapbox Token. You can get it from here https://account.mapbox.com/access-tokens/
import React, { useState } from "react";
import ReactMapGL, { Marker } from "react-map-gl";
import "./styles.css";
export default function App() {
const [viewport, setViewport] = useState({
latitude: 50.826758,
longitude: 4.380197,
width: "100vw",
height: "100vh",
zoom: 3
});
const YOURMAPBOXTOKEN = "";
const posts = [
{
id: 1,
latitude: 50.826758,
longitude: 4.380197
},
{
id: 2,
latitude: 48.893615,
longitude: 2.490906
},
{
id: 3,
latitude: 51.454007,
longitude: -0.235523
}
];
const [selectedProperty, setSelectedProperty] = useState(null);
const [isPopupShown, setIsPopupShown] = useState(false);
return (
<div className="root">
{!isPopupShown && (
<div className="map">
<ReactMapGL
{...viewport}
mapboxApiAccessToken={YOURMAPBOXTOKEN}
mapStyle="mapbox://styles/mapbox/dark-v9"
onViewportChange={(viewport) => {
setViewport(viewport);
}}
>
{posts &&
posts.map((item) => (
<Marker
key={item.id}
latitude={item.latitude}
longitude={item.longitude}
>
<button
className="marker-btn"
onMouseEnter={() => {
setSelectedProperty(item);
setViewport({
latitude: 50.826758,
longitude: 4.380197,
width: "0vw",
height: "0vh",
zoom: 3
});
setIsPopupShown(true);
}}
>
<img src="placeholder.svg" />
</button>
</Marker>
))}
</ReactMapGL>
</div>
)}
{/* SHOW FULL CUSTOM POPUP HERE */}
{selectedProperty && isPopupShown && (
<div className="full-popup">
// todo: create a closing popup button here
</div>
)}
</div>
);
}
Todo: you have to create a closing popup button for the custom Popup.
You can do it by reversing my code like this:
Set selectedProperty into null.
Set isPopupShown into false.
Sett the width and height of the viewport into 100%.

How to stop my scrollbar from pushing my header?

I have this problem with my scrollbar that's overriding my header, is there some CSS property I can use to move the scrollbar "on-top" of my header? I have a transparent background which I thought would do the job.
Basically, how can I make my scrollbar hover above the header, instead of pushing it to the left?
As you see in the pic, the scrollbar is taking over the full width of the header.
Here is my scrollbar CSS:
'#global': {
'*': {
'scrollbar-width': 'thin',
}
,
'*::-webkit-scrollbar': {
width: '1rem', height: '1rem',
}
,
'*::-webkit-scrollbar-thumb': {
backgroundColor: '#d6dee1', borderRadius: '20px', border: "6px solid transparent", backgroundClip: 'content-box',
}
,
'*::-webkit-scrollbar-thumb:hover': {
backgroundColor: '#a8bbbf'
}
,
'*::-webkit-scrollbar-track': {
backgroundColor: 'transparent',
}
}
You can add a margin-top for the webkit-scrollbar-track :
'*::-webkit-scrollbar-track': {
backgroundColor: 'transparent';
margin-top: 10px;
}
This post explains it pretty good: Change scrollbar height
EDIT:
This post has a very similar problem:
How to get a scrollbar in a div with fixed header and footer?
The problem there was solved by fixing the header.

How to increase automatic height of matdialogbox in angular 5?

uploadFiles(): void {
const dialogRef = this.dialog.open(AddNewFilesOrImagesComponent, {
width: '620px',
height : '100%',
});
}
if height 100 % UI looks like this(under upload button not necessary empty spaces)
if I put fix height in px(it makes UI scrollable)
uploadFiles(): void {
const dialogRef = this.dialog.open(AddNewFilesOrImagesComponent, {
width: '620px',
height : '250px',
});
}
I want actual this type if I SELECT File it automatic increase its height(when i choose image that time i want to increase automatic height of matdialogbox)
Try this, it will take complete height of the page for your matdialog
uploadFiles(): void {
const dialogRef = this.dialog.open(AddNewFilesOrImagesComponent, {
width: '100%',
minHeight: 'calc(100vh - 90px)',
height : 'auto'
});
}
The dialog does automatically adapt to the content as long as its html is wrappend inside mat-dialog-content. :
<h1 mat-dialog-title>{{data.title}}</h1>
<div mat-dialog-content>...>
<div mat-dialog-actions>...>
The default max height of content of material dialog is 65vh. It can be increased by styling .mat-dialog-content
::ng-deep {
.mat-dialog-content {
max-height: 90vh;
}
}
Add a class to your dialog:
uploadFiles(): void {
const dialogRef = this.dialog.open(AddNewFilesOrImagesComponent, {
panelClass: 'myClass',
});
}
Then add the following style to the class in your CSS:
.myClass {
max-height: 95%;
width: 620px;
overflow-y: auto;
}

Show "show more" dynamically

I have created a forum-like page where all messages are as follows (simplified):
<div class="message-wrapper" *ngFor="let node of allNodes">
<div [class]="isExpanded(node.id) ? 'message-content expanded' : 'message-content'">
<div class="content" [innerHtml]="node.comment"></div>
<span (click)="toggleExpand(node.id)" class="showMore">{{ isExpanded(node.id) ? 'Show less' : 'Show more' }}</span>
</div>
</div>
And the css
.message-content {
overflow-y: hidden;
.content {
line-height: 1.5vh;
max-height: 6vh;
overflow-y: hidden;
}
}
.message-content.expanded {
max-height: 10000000vh;
overflow: visible !important;
.content {
overflow: visible;
max-height: 100000000vh;
}
}
And when clicking the 'Show more' and 'Show less' span, the div.content expands as expected.
The problem I'm currently encountering is that I want to show the 'Show more' only when the text is actually overflowing.
I know I can find this out by subtracting the scrollHeight and innerHeight but for this to work, I need to have the correct (unique) nativeElement of the corresponding div.comment in my controller.
So my question:
How can I show the 'Show more' span, when the div.content is overflowing while all Messages on the page have the same classes etc.?
The thing that makes this question unique from existing questions is that I don't have a single element but I have multiple of the same elements (multiple messages) thus needing the unique node element.
Created a workaround where I'd add a dynamic id to all divs and spans. Then I loop through all nodes and check if the text is overflowing. If it is I set hidden=false to the label.
for(let comment of this.allComments) {
//element which contains the comment content
let content = document.getElementById('div'+comment.id);
// if the element height is bigger than the displayed height (with an error margin of 10)
if(content.scrollHeight - content.clientHeight > 10) {
// the corresponding 'show more' label
let label = document.getElementById('label'+comment.id);
label.hidden = false;
}
}

ng repeat with relative position elements not sized correctly

I am using angularjs and zurb foundation. I have ng-repeat creating a row for each item in items. Each row itself has two rows within. I am using position relative to move the second inner row up behind the first inner row. The first row has z-index 1 to move it on top. The goal is to create a menu that is hidden behind a div initially.
Seems to work except for one flaw. The problem I am having is that it seems that the directive has its height set to the initial height of its content. So the directive is 12em tall while the content is only in the top half.
Forcing the directive to be 6em tall works for the first item but the subsequent ones have the content of the back row all jibbly wibbly! (I believe that is the scientific term)
Any help would be appreciated. Smashing my head against the keyboard is usually my 'go to' in these situations, but it hasn't helped in this case.
Sample
//index.html
<div ng-repeat='item in items'>
<div directive></div>//ends up 12em
</div>
//directive.html
<div class="row front">//6em tall
//content
</div>
<div class="row back">//moved 6em up
//Menu with buttons
</div>
//style.css
front: {
height: 6em;
z-index: 1;
}
back: {
height: 6em;
position: relative;
top: -6em;
}
The problem is that you are trying to position two divs with relative positioning. They don't need to be relative since they are intended to occupy the same space.
Make the parent div use relative positioning:
.parent { position: relative; }
.front { position: absolute; top: 0; height: 6em; }
.back { position: absolute: top:0; height: 6em }
https://docs.angularjs.org/api/ng/directive/ngRepeat
This is how I would do it:
app.directive('row front', function() {
return {
restrict: '6pm',
scope: {
collection: '=',
columnCount: '='
},
transclude: true,
template: '<div><div class="column" ng-repeat="col in cols">' +
'<div ng-repeat="item in col" ng-transclude></div>' +
'</div></div>',
link: function( scope ) {
var partition = function partition( size, items ) {
if ( items.length === 0 ) { return []; }
return ([items.slice( 0, size )]).concat( partition( size, items.slice( size )));
};
var relativenize = function() {
if ( !scope.columnCount ) { return; }
scope.cols = partition( scope.columnCount, scope.collection );
};
scope.$watch('columnCount', columnize );
scope.$watch('collection', columnize );
}
};
});