Blazor virtualization with row grouping - html

Im creating a grouped list with sticky header. Really would like to use virtualization with it. But the virtualization doesnt work when i set fixed height and overflow on the top level table-content-container. Virtualization only works when fixed height and overflow is set to group-body-container.
Here's the html i got what does not work:
<div class="table-container">
<div class="table-header grid-row-template">
<div class="header-item">Id</div>
<div class="header-item">Name</div>
</div>
<div class="table-content-container" style="height:50vh; overflow-y:scroll">
#foreach (DataGroup group in dataGroups)
{
<div class="group-header">
<MudToggleIconButton
#bind-Toggled="#group.IsExpanded"
Icon="#Icons.Filled.ExpandMore"
Color="Color.Secondary"
ToggledIcon="#Icons.Filled.ExpandLess"
Size="Size.Small"
ToggledSize="Size.Small"/>
<MudText Color="#Color.Primary">#group.GroupName</MudText>
</div>
#if (group.IsExpanded)
{
<div class="group-body-container">
<Virtualize Items="group.DataRow" Context="row" ItemSize="20">
<div class="grid-row-template data-row">
<div class="data-item">#row.Id</div>
<div class="data-item">#row.Name</div>
</div>
</Virtualize>
</div>
}
}
</div>
</div>
Here the virtualization works: https://try.mudblazor.com/snippet/GEcwagOjgXcmYqFL
Here its not working: https://try.mudblazor.com/snippet/GawcYUuNUXbCiTTY
The goal would be to have the virtualization working with the second example, when scrolled only the top header would be "sticky".
EDIT:
Here's recording of what i would like to achieve but with working virtualization (https://try.mudblazor.com/snippet/GawcYUuNUXbCiTTY):
Is this even possible with blazors virtualization component?

It is because the Virtualize component needs a limiting height - either explicit or implicit. As you have it now, each Virtualize can just grow to consume as much space as it needs.
You can make your container use flexbox and your group container have a min/max height of 100% to achieve this:
.table-content-container {
display: flex;
flex-direction: column;
gap:0;
}
.group-body-container {
min-height: 100%;
max-height: 100%;
overflow: auto;
}
Updated demo #2 where the expanded group matches the container height - but without more information about what you are trying to do this could go on forever....:
https://try.mudblazor.com/snippet/wOQwEKbUdhZHlbiE
To round things off - I do not recommend this design, but to show it is possible, you can also hide the scrollbars on the expanded/virtualised groups with CSS
.group-body-container {
min-height: 100%;
max-height: 100%;
overflow: auto;
}
.group-body-container {
scrollbar-width: none; /* Firefox */
}
.group-body-container::-webkit-scrollbar {
display: none; /* Safari and Chrome */
}
Here is a demo: https://try.mudblazor.com/snippet/cammugcNEmPoITgg - with a scrollbar only on the main container, so you can only scroll the virtualized groups contents with mousewheel/touch - which is why I don't like it.

Related

Flexbox: Two even columns - big image (with aspect-ratio) and content

I need to create an information section that includes an image and content next to it.
It should look like this:
I have already written a little bit of code, but it does not seem to be the best solution: everything works fine, but code is not graceful.
Please, have a look:
/* Simple reset */
img {
display: block;
max-width: 100%;
}
body {
background-color: black;
}
.information {
display: flex;
gap: clamp(5rem, 10vw, 8rem);
}
.information > * {
width: 50%; /* Using the 'width' property. */
}
.information-content {
align-self: center;
color: white;
}
.information-image {
align-self: flex-start;
object-fit: cover;
aspect-ratio: 1 / 1.10;
border-radius: 5px;
}
<section>
<div class="container">
<div class="information">
<img
class="information-image"
alt="Products for companies & Startups"
src="https://s3-alpha-sig.figma.com/img/6630/3672/40959a0086f9fbb8418c0829b277dd93?Expires=1670198400&Signature=gpQ5NqRXp9omRHkjCl718I9WPLqfx4xPKp1CQSMKbEnRCU7izmQIXkcn6zI6Z17p8Q7Li-wBAXb3P2Jg9qEuJauFeKqErbl4jgW950K35-LeX394hN7fJ7UEPmkgGSqB-drY1QdU7NZVV4QKTrZ0QBuw47xVBPOOfJMQO8NPOpZkx43UbbkS1yGgnxN5tELyriz9e8pH6pXO8AnJx7zvGz4mm3InyHOySUcb3ibVPa9XKJ8fyxPnkBeVoYFvwpiVddEs7uVNqCkCRuN2dJIIQg78FB-6TYX13nQ~NxvhG2059ks2q52a9p0N-DSmSYE-Yt-jedbJ1fEt3cZVnIfzUw__&Key-Pair-Id=APKAINTVSUGEWH5XD5UA"
/>
<div class="information-content">
<h2>
My main goal is to keep my customers satisfied.
</h2>
<p>
Even with skills that are primarily mental, such as
computer programming or speaking a foreign language.
</p>
<p>
Even with skills that are primarily mental, such as
computer programming or speaking a foreign language.
</p>
</div>
</div>
</div>
</section>
My concern is the width property set on each child of my flex parent. As far as I know, using width inside flexbox is not the best idea? However, when I try to use the flex-basis property, everything breaks.
Note: I cannot use display: grid because the image can be after the content - with grid I will have to change the order and the code will become more complicated.

How permanently align div of a stacked element

I need to move all div inside of container up to a div above it
<div class="gb-box-holder">
<!-- GUIDE BOX -->
<div class="gb-box gb-box-1">
<div class="gb-header">
<span class="gb-decor-top"></span>
<div class="gb-logo">
<img class="gb-img" src="http://www.scim.si/wp-content/uploads/2015/01/apply.jpg" alt="">
<div class="gb-logo-cover"></div>
</div>
<h3>Lorem ipsum dolor</h3>
<!-- <span class="gb-decor-top"></span> -->
</div>
<div class="gb-container">
<span class="gb-decor-container"></span>
<p>
Lorem
</p>
<a class="gb-btn-guide" href="#"> Reed more</a>
</div>
</div>
<!-- GUIDE BOX -->
</div>
BOXES SECTION END -->
#gd-section .gb-box-holder {
display: flex;
display: -webkit-flex;
flex-wrap: wrap;
-webkit-flex-wrap: wrap;
justify-content: top;
-webkit-justify-content: top;
}
#gd-section .gb-box-holder .gb-box {
display: block;
width: 246px;
background-color: #303030;
margin: 5px;
float: left;
}
.gb-box class of each div
ps. Sorry for my spalling, English not my mother language
There are multiple ways You can approach this. The wrap that flex creates is only horizontal and not vertical - therefore, you won't be able to stack an item upwards. So it must be done in a column-wise manner. You just have to invert things in order for it to work like You want it to.
Here is a way to do this using Flex.
Another way of doing this is using HTML Columns which is your quickest option here but it will not be responsive in all browsers, therefore you will need to use prefixes and manual adjustments.
div {
-webkit-columns: 100px 3; /* Chrome, Safari, Opera */
-moz-columns: 100px 3; /* Firefox */
columns: 100px 3;
}
You can find a good tutorial on this here.
The other more fool-proof way is to use a plugin called CSS Masonry which uses JavaSript to align your items in a certain way. The only con here is that it will add a bit of js bulk to your code and it will be a bit time consuming. But it will be responsive and perfectly aligned.
If you decide to go along the CSS column path, this CodePen will do you good as well.
You can not achieve this with flexbox but you might want to try using css columns although they are meant to be used for text.
.gb-box-holder {
columns: 200px 3;
}
http://codepen.io/ingvi/pen/EgAZwz/

css not affecting the page when using with bootstrap

I am a newbie to bootstrap. I have developed a weppage using bootstrap3. I'm using these two classes on the same element, but the css is not having any effect:
HTML:
<div class="col-md-4 auminascroll">
dfgdgdfgdfgsdfgh cxzvdzfhfdbfd fbfddf
</div>
<div class="col-md-4 auminascroll">fghfdghfdhdfhfdsh</div>
<div class="col-md-4 auminascroll">dfgdsgdsfg</div>
Css:
.col-md-4 .auminascroll {
height: 50px;
overflow-y: auto;
}
I am not getting a scroll when using above code. If I put height: 50px; overflow-y: auto; in a style tag, my code works fine. Why is this css not having an effect when using it with this bootstrap class? Is there any problem with my code?
Any help will be greatly appreciated!!!
You're nearly there! When using a selector to choose two classes there should be no space between the class names - they just need separating with a dot.
.col-md-4.auminascroll { /* no space between the two classes */
height: 50px;
overflow-y: auto;
}
Your code (where there's a space between the two classes: .class-a .class-b would actually look for an element of class-b inside and element of class-a.
<div class="col-md-4">
<div class="auminascroll">
</div>
</div>
You are using the wrong css selector. You need to use it like:
.col-md-4.auminascroll {
height: 50px;
overflow-y: auto;
}

Hide scrollbar in firefox

I want to hide a scroll bar in page but I can scroll like it has a scroll bar.
so I cant use overflow:hidden because I want that I can scroll like normal
but cannot see a scroll bar.
so I use this css code (class not-scroll-body is a class of body tag)
.not-scroll-body::-webkit-scrollbar {
display: none;
}
It works in Chrome , but when I use -moz- instead of -webkit- like this
.not-scroll-body::-moz-scrollbar {
display: none;
}
It doesn't work in Firefox.
What can I do to to make it work?
Thank you for every answer and sorry for my poor english language :)
In firefox 64, if you want to hide scroll when you have overflow:auto you can now do scrollbar-width: none;! Woop woop! Here are the relevant docs (browser support is show at bottom of page).
Below is a simple css only solution that will hide your vertical and horizontal scrollbar in firefox (tested in v64 & firefox dev edition v65.0b8). Hint: try vertical and horizontal scrolling on the blue div.
.not-scroll-body {
overflow: auto;
height: 200px;
width: 90%;
background: linear-gradient(to bottom, cyan, blue);
white-space: no-wrap;
/* the line that rules them all */
scrollbar-width: none;
/* */
}
span {
width: 200%;
height: 400%;
background: linear-gradient(to left, green, yellow);
display: inline-block;
margin: 5rem;
}
<div class="not-scroll-body"><span></span></div>
According to this answer and everything I've been able to find on the web, there's no Firefox equivalent of the -webkit-scrollbar selector. Apparently there used to be a property, -moz-scrollbars-none, that you could use for this, but it's since been removed and people recommend using overflow:hidden or a hackish margin-right: -14px solution.
Sorry I can't be more helpful -- it seems like there's no Firefox way to do this elegantly.
I was able to hide the scrollbar but still be able to scroll with mousewheel with this solution:
html {overflow: -moz-scrollbars-none;}
Download the plugin https://github.com/brandonaaron/jquery-mousewheel and include this function:
jQuery('html,body').bind('mousewheel', function(event) {
event.preventDefault();
var scrollTop = this.scrollTop;
this.scrollTop = (scrollTop + ((event.deltaY * event.deltaFactor) * -1));
//console.log(event.deltaY, event.deltaFactor, event.originalEvent.deltaMode, event.originalEvent.wheelDelta);
});
cf: https://stackoverflow.com/a/41021131/4881677
This is how I do it, only CSS and works well with frameworks like bootstrap. It only needs 2 extra div:
You can select the text to make it scroll or scroll it with fingers if you have a touchscreen.
.overflow-x-scroll-no-scrollbar {overflow:hidden;}
.overflow-x-scroll-no-scrollbar div {
overflow-x:hidden;
margin-bottom:-17px;
overflow-y:hidden;
width:100%;
}
.overflow-x-scroll-no-scrollbar div * {
overflow-x:auto;
width:100%;
padding-bottom:17px;
white-space: nowrap;
cursor:pointer
}
/* the following classes are only here to make the example looks nicer */
.row {width:100%}
.col-xs-4 {width:33%;float:left}
.col-xs-3 {width:25%;float:left}
.bg-gray{background-color:#DDDDDD}
.bg-orange{background-color:#FF9966}
.bg-blue{background-color:#6699FF}
.bg-orange-light{background-color:#FFAA88}
.bg-blue-light{background-color:#88AAFF}
<html><body>
<div class="row">
<div class="col-xs-4 bg-orange">Column 1</div>
<div class="col-xs-3 bg-gray">Column 2</div>
<div class="col-xs-4 bg-blue">Column 3</div>
</div>
<div class="row">
<div class="col-xs-4 bg-orange-light">Content 1</div>
<div class="col-xs-3 overflow-x-scroll-no-scrollbar">
<div>
<div>This content too long for the container, so it needs to be hidden but scrollable without scrollbars</div>
</div>
</div>
<div class="col-xs-4 bg-blue-light">Content 3</div>
</div>
</body></html>
Short version for lazy people:
.overflow-x-scroll-no-scrollbar {overflow:hidden;}
.overflow-x-scroll-no-scrollbar div {
overflow-x:hidden;
margin-bottom:-17px;
overflow-y:hidden;
width:100%;
}
.overflow-x-scroll-no-scrollbar div * {
overflow-x:auto;
width:100%;
padding-bottom:17px;
white-space: nowrap;
cursor:pointer
}
/* the following classes are only here to make the example looks nicer */
.parent-style {width:100px;background-color:#FF9966}
<div class="parent-style overflow-x-scroll-no-scrollbar">
<div>
<div>This content too long for the container, so it needs to be hidden but scrollable without scrollbars</div>
</div>
</div>
I assuming you want to hide the scrollbar locally. In that i mean, not on a web server for the world to see, but on your local copy of firefox, for your 'viewing pleasure' only.
this is what I've found to work for me on opensuse/kde:
in userChrome.css;
#content browser {
margin-right -12px !important;
overflow-x:hidden;
overflow-y:scroll;
}
use -14px to completely hide vertical-scroll (more if your system theme has wider scroll setting). I use less (10px) to see just a little of it so I can middle-click to jump to a place on the page.
thing that i did, but don't always work, any longer:
in userContent.css
#content browser {
overflow:-moz-scrollbars-none;
}
-or-
html {
overflow: -moz-scrollbars-none;}
}
above used to work, but I now I've lost the mouse-wheel scroll. Only keyboard arrow keys work now.
Hope I understood what you want and this helps.
Landis.
You might be able to use overflow:-moz-hidden-unscrollable -- this worked perfectly for my needs in part because I was already using dragscroll.js.
As I was looking for it myself and this thread is not providing the updated answer, I would provide it for other newcomers as myself.
#element{
scrollbar-width: none;
}

PhoneGap/Cordova: Prevent horizontal scrolling

I have an app built on Cordova and on some of my pages I am able to scroll horizontally out of my content into white space.
This is weird as I have nothing there that extends beyond my #wrapper, which is set to width: 100%.
So I was wondering if there was a way I could disable horizontal scrolling in the app altogether?
UPDATE:
Code on page as requested:
body {
background-color: #fff;
font-family:Arial, Helvetica, sans-serif;
color: #b7b8b9;
height: 100%;
width: 100%;
}
iframe{
border: none;
width: 100%;
/*margin-top: 50px;*/
}
#header{
height: 50px;
width: 100%;
}
<body>
<div id="wrapper">
<div id="header">
<div class="headerback">Home</div>
<div class="headerrefresh"><script>var pathname = window.location.pathname;</script><script>document.write('Refresh')</script></div>
<div class="headertitle"><h2>Get the Look</h2></div>
</div><!--HEADER-->
<iframe src="http://www.mbff.com.au/getthelook"></iframe>
</div>
</body>
Try to debug your page in Chrome (webkit) with the exact dimensions of your device. This solves most rendering issues for me.
I do not know the specific issue here, but it looks like one of your elements is flowing outside of the wrapper. You could for example try this in your css:
div.wrapper { overflow: hidden; width: inherit; }
Although it might be a better idea to find out why your page is expanding horizontally?
I was looking for the solution to this problem for a long time.
Finally I solved it in the following way.
I set style for bodyand html tags:
position: fixed;
width: 100%;
height: 100%;
overflow: hidden;
After that I've added div to body and set the style for it:
overflow-y: auto;
height: 100%;
So, I have got fixed body, which contains div with vertical scroll bar.
// Phone Gap disable only horizontal scrolling in Android.
// Add this code in your Phone Gap Main Activity.Initially Declare the variable
private float m_downX;
//Then add this code after loadUrl
this.appView.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
// save the x
m_downX = event.getX();
}
break;
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP: {
// set x so that it doesn't move
event.setLocation(m_downX, event.getY());
}
break;
}
return false;
}
});
Try adding the following code to your .html file:
document.body.addEventListener('touchmove', function(event) {
event.preventDefault();
}, false);
For the sake of completeness, I thought the answer which makes use of the official method of doing such a thing via the preference tag should be added:
<preference name="DisallowOverscroll" value="true"/>
Supported by Android and iOS according the documentation.
Default: false
Set to true if you don't want the interface to display any feedback when users scroll past the beginning or end of content. On iOS, overscroll gestures cause content to bounce back to its original position. on Android, they produce a more subtle glowing effect along the top or bottom edge of the content.
In my case it was broken styling like below
<body>
<div style="margin-left:5%; width:100%">Content</div>
</body>
which cause div to became horizontally bigger than body. I could see scroll when app run in browser. Set width to 90% (as it was initially intended) fixed the problem.
Generally, as it already pointed out here, enough to find element with wrong style which makes your page expanding horizontally and fix it.
BTW DisallowOverscroll was not helpful in above case.