I'm trying to implement a virtual scroll in my image gallery. My problem is that the implementation doesn't work correctly. First, the elements are displayed in vertical position, when in fact they should respect the horizontal breakpoints and only then respect the vertical scroll. Second, with the scroll elements appear with huge spacing.
Does anyone know how I can solve this problem? thanks
DEMO
HTML
<div [ngSwitch]="viewMode" style="height:100%; width:100%">
<div id="tab2" *ngSwitchCase="'tab2'" style="height:100%; width:100%">
<div
style="margin-left: 16px; margin-right: 16px;height:100%; width:100%"
class="first"
>
<ng-container
*ngIf="
arrayDeNomesCategorias.length == 0 ||
arrayDeNomesCategorias == undefined
"
>
<ul
class="mdc-image-list my-image-list"
style="height:100%; width:100%"
>
<cdk-virtual-scroll-viewport
itemSize="50"
style="height:100%; width:100%"
>
<ng-container *cdkVirtualFor="let i of images; let j = index">
<li class="mdc-image-list__item">
<div class="mdc-image-list__image-aspect-container">
<img
src="https://material-components-web.appspot.com/images/photos/3x2/{{
i + 1
}}.jpg"
class="mdc-image-list__image"
/>
</div>
</li>
</ng-container>
</cdk-virtual-scroll-viewport>
</ul>
</ng-container>
</div>
</div>
</div>
Problem
Correct, but without the implemented scroll :(
I updated your example here.
Your problem was mainly css and there seem to have been (at least) 2 problems:
Your are giving .mdc-image-list__item class min-height: 400px and max-height: 400px. That basically means that all your .mdc-image-list__item containers will have 400px height (so height: auto is kind of useless). Removing this will remove the white space between your images.
If you want to have scroll as well as elements on the same page you should use a flex container with flex-wrap: wrap.
In order to do this I used the following snippet (for your case):
:host ::ng-deep .cdk-virtual-scroll-content-wrapper {
display: flex;
flex-wrap: wrap;
}
You can read more about host and ng-deep here. But please be aware that according to this article (and not only) is recommended to avoid using it in recent version of angular. For the sake of simplicity I used it on your example but you might want to avoid it in production.
(extra) : As a small improve I also removed the duplicated margin: 10px; height: auto; max-height: 400px; properties from .mdc-image-list__item media queries (and only leaved the initial one with no media query). It will be applied anyway since there isn't anything to overwrite it and just changing just the with on the media queries should be enough.
Related
I am in the process of making my own website, and I am making it out of pure HTML. I encountered in the making of the page, as I will describe below.
Here's my code for reference :-
<head>
<style>
img {
display: block;
margin-left: auto;
margin-right: auto;
}
</style>
<style>
.sideDiv {
border: 1px outset black;
background-color: white;
text-align: center;
width: 120;
height: 400;
}
</style>
<style>
.mainDiv {
border: 1px outset black;
background-color: white;
text-align: left;
width: 400;
height: 300;
}
</style>
<img src="AyushLogo.png" alt="logo" height="9.2%" width="9.2%" style="float:left">
<br>
<a><button>About Me</button></a>
<a><button>Games</button></a>
<a><button>My Blog</button></a> <br><br>
<hr>
</head>
<body>
<div class="sideDiv">
</div>
<div class="mainDiv">
<p>Hi,<br>My name is Ayush Bhatt.<br><br>I love to code and remake old games. You can view some of my games by clicking on the 'Games' button on the top bar.</p>
</div>
</body>
</html>
The output looks like this :-
I wanted the tag with the "mainDiv" properties to appear at the side of the one with the "sideDiv" properties, but it just doesn't want to.
PS : I want to use only HTML as long as possible
An important thing about <div> tags is that they are known as "block-level" elements, which in particular means that they always start on a new line and take up the full width available, regardless. With this in mind,
writing
<div class="sideDiv"></div>
<div class="mainDiv">
...
</div>
should result in a div with class sideDiv and width as defined in the class, and then a new div with class mainDiv started on a new line, as block-level elements do by default, though note that this is simultaneously also because the div with class sideDiv takes up the remaining width on the page as a block-level element (though its content width is as described in the class, it being a block-level element is a bit like it "reserving" the rest of the width even though its content only uses the amount defined), so the next element (block level or inline) can only start on at least the next line.
If you want to circumvent this behavior, there are many ways to do it. One is by using an external tool like bootstrap, as pointed out by another answer, but my favorite is to simply use flex box. This can be done for your code in this way
<div style="display: flex; flex-direction: row;">
<div class="sideDiv"></div>
<div class="mainDiv">
...
</div>
</div>
A method that directly overwrites the block-level property would be to set the style display: inline-block; for both divs, to prevent either from starting on a new line or taking up the whole available width by default. (Just one isn't enough, if you only set it on the first one, the second still starts on a new line by default, and if you only set it for the second one, the first still takes up all available width by default). However, this causes the element to be treated completely as an inline element besides the fact that block-level height and width can be applied, and can be strange/difficult to maneuver as a result. It is often easier to just use a flex box. Code for this would be
<div class="sideDiv" style="display: inline-block;"></div>
<div class="mainDiv" style="display: inline-block;">
...
</div>
However, note that <p> is also a block-level element, so directly substituting in your original code in the mainDiv div would still cause it to skip a line before displaying. Again, it is usually easier, more modern, and better looking to just use a flex box.
Edit: Added the detail about block-level elements taking up all available width, and fixed the incorrect initial method that changed the display property to overwrite the block-level property by setting display: inline;. This can work, but it will ignore the heights and widths of the <div>s.
try using bootstrap , it deals with layout perfectly , here is an example :
<div class="container">
<div class="row">
<div class="col-md-6">
this is the left section
</div>
<div class="col-md-6">
this is the right section
</div>
</div>
</div>
for more details check :
https://getbootstrap.com/docs/5.0/layout/grid/
NOTE : you will need to include bootstrap and jQuery libs , check for online tutorial to start using bootstrap
I have an ag-grid table that changes its size dynamically based on some buttons. more or less columns will be added or removed from the table. However, as the number of columns increases, the table would eventually spill out of the page, which cannot be seen. I have tried to apply horizontal scrolling but to no avail.
This is my code:
<div class="row text-center" style="justify-content: center;">
<div>
<ag-grid-angular
style="font-size: 15px; width: 100%;"
class="ag-theme-balham"
[rowData]="data"
[columnDefs][="columnDefs"
[defaultColDef]="defaultColumnDefs"
(gridready)="onGridReady($event)"
</ag-grid-angular>
</div>
</div>
Basically, I want either two of the followings:
the width of the ag-grid table to be fixed and horizontal scrolling enabled
OR the width of the ag-grid table can grow depending on the number of columns. However, it should not spill out of the page.
And also, I would like the table to be centralized in the middle of the page as well.
Thanks!
You can try:
<ag-grid-angular
style="font-size: 15px; width: 100%;"
class="ag-theme-balham"
[rowData]="data"
[columnDefs][="columnDefs"
[defaultColDef]="defaultColumnDefs"
(gridReady)="onGridReady($event)"
(gridSizeChanged)="onGridSizeChanged($event)
</ag-grid-angular>
onGridReady(params: GridReadyEvent) {
params.api.sizeColumnsToFit();
}
onGridSizeChanged(params: GridSizeChangedEvent) {
params.api.sizeColumnsToFit();
}
I see your grid takes 100% width, make sure the parent div has a fixed width. To center the grid, I see you have done justify-content: center; which is good but make sure this div has display: flex; on it.
gridSizeChanged will be called every time the grid size changes and then we call sizeColumnsToFit so this will shrink all columns to fit with the fixed width.
I know there are a lot of these questions already answered but non that fit my requirements. I have a table of unknown height and width and I need to, if the table is too high so that one needs to scroll through it, that the table headers stay fixed and follow the scroll. All solutions I've seen require a fixed height of the table. I would also want the scroll to be invisible while still functional. Can this be accomplished or do I need the fixed height?
My CSS so far allows me to scroll both vertically and horizontally (I only want the vertical scroll) but with fixed height and visible scroll bar:
table.sol-compare-table {
box-sizing: border-box;
overflow: hidden;
display: table;
width: 100%;
}
table.sol-compare-table thead, table.sol-compare-table tbody {
float: left;
width: 100%;
}
table.sol-compare-table tbody {
overflow: auto;
height: 150px;
/*overflow-x: hidden;*/
}
table.sol-compare-table tr {
width: 100%;
display: table;
text-align: left;
}
Here is my HTML:
<table class="table sol-compare-table">
<thead>
<tr>
<th>
<div>
<a class="sol-pdf-generator hover-gray-icon sol-share-icon" target="_blank" ng-href="#">
<i class="fa fa-file-pdf-o"></i>
Ladda ner som PDF
</a>
<a class="sol-share-facebook hover-gray-icon sol-share-icon" onclick="#">
<img src="#" alt="facebook">
</a>
<a class="sol-share-twitter hover-gray-icon sol-share-icon" onclick="#">
<img src="#" alt="twitter"><!--<i class="fa fa-twitter"></i>-->
</a>
<a class="sol-share-mail hover-gray-icon sol-share-icon" onclick="#">
<i class="glyphicon glyphicon-envelope"></i>
</a>
</div>
<h2 class="sol-compare-heading">Allmän Information<h2>
</th>
<th ng-repeat="unit in units" class="sol-compare-heading">
<div>
<a href="#/unitDetail/{{unit.Id}}">
<img class="detail-main-image" ng-if="getImageOfUnit(unit).Value.Id" ng-src="#"></img>
</a>
</div>
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="#">
<td>Name</td>
<td ng-repeat="unit in units">
<span ng-if="unitAttr.Value != null">
<span print-attribute="#"></span>
</span>
<span ng-repeat="#" ng-if="unitAttr.Values">
#
</span>
<span ng-if="# == null && unitAttr.Values == null">
-
</span>
</td>
</tr>
</tbody>
</table>
EDIT
I tried with using position:fixed at the table header and that almost accomplish what I'm after, only that it should be fixed at the top of the page at all times (when scrolling down it should follow the scroll but the same position in the browser window). This JSfiddle is the easiest way to show where I'm at atm I guess; http://jsfiddle.net/rwqkokgy/5/
For vertical scrollbar You have to use overflow-y:scroll; overflow-x:hidden;
You can use overflow-y:auto; and vertical scrollbar will be show/hide depend of table content.
There is one example, but with two tables. First one is header and second for table content. Maybe You can achieve on this way.
jsfiddle example
In this example is one button, too. For simulating with and without scrollbar, depending of table content.
That button and js function called chVl You can remove. First function called checkW is used if You resize Your browser.
I hope so this will help You.
Edit :
If You want vertical scrollbar all time, then do next (in provided jsfiddle example) :
Remove onload and onresize from body
Remove complete javascript
In #container (css) for overflow-y replace from auto to scroll
About height in #container, You can change it by Your needs.
And, of course, remove that button, like i wrote above. His purpose is just for simulation, nothing else.
I'm now using an Angular directive called "sticky" which makes it so that the "sticky" element (which I set to be the table header) sticks to the top of the screen when scrolling.
For more information about this directive, please follow this link: http://angularscript.com/angularjs-directive-create-fixed-elements-scroll-angular-sticky/
It was very easy to implement and required almost no coding at all.
I'm trying to make a movie manager to get me back working with rails again. I'm reading the movies from a database, and trying to present their covers in a responsive grid.
I'm new to using Twitter Bootstrap, and having some weird issues with weird spacing. All my images are the same height and width, so that shouldn't be an issue.
To see the issue, go here: http://jsfiddle.net/32AcT/ (Due to the responsive grid, you may have to make the view window bigger, so they're not all in a single column.) I'm simply doing:
<ul class="thumbnails">
<li>
<a href="#">
<div class="caption">2 Fast 2 Furious</div>
<img alt="2 Fast 2 Furious" class="thumbnail" height="111" src="http://cf2.imgobject.com/t/p/w500/4rDV8TgaILHRfX1IRgpysjkD9A0.jpg" width="74" />
</a>
</li>
...
</ul>
Here is an example of what it looks like (weird spacing highlighted with pink box):
I understand why the widths are off, due to the caption lengths being longer than the image's width (although I'd like to fix that somehow too). Why is this happening, and is there any good method to prevent it?
try this one i think it will solve your prblem
http://jsfiddle.net/32AcT/1/
.thumbnails > li { width:100px; }
.thumbnails .caption{ overflow :hidden; text-overflow:ellipsis; white-space:nowrap; }
.thumbnails img{ height:111px; width:74px}
main issue with bootstrap-combined.min.css line no 23 height:auto;
img {
max-width: 100%;
width: auto 9;
height: auto;
vertical-align: middle;
border: 0;
-ms-interpolation-mode: bicubic;
}
If I get the problem right, the caption is causing it. What would you say to a solution like this: http://jsfiddle.net/32AcT/4/
The difference from your solution is that the Caption is inside the thumbnail (seen in code 1) div and thus is limited in the width (seen in code 2). It could be that you have to play a round with the height of the div but I guess that would be the "best" solution for this.
Code 1:
<li class="span4">
<div class="thumbnail">
<img src="http://cf2.imgobject.com/t/p/w500/1ZjDmPKMUtout8hR77qmK1llgls.jpg">
<div class="caption">
<h3>Along Came a Spider</h3>
<p>Action Action</p>
</div>
</div>
</li>
Code 2:
.thumbnail{
height:650px!important;
}
I want to construct a timeline that has horizontal scrolling.
I have a wrapper DIV, inside it has months. Each month is a DIV inline-block. This works:
<div class="wrap">
<div class="month">Jan 2013</div>
<div class="month">Feb 2013</div>
...
</div>
This almost works, but because my clients site uses tables for layout the scroll bars don't work. This fails:
<table><tr><td>
<div class="wrap">
<div class="month">Jan 2013</div>
<div class="month">Feb 2013</div>
...
</div>
</td></tr></table>
Here is a jsfiddle to show what I mean: http://jsfiddle.net/fhL9u/2/
NOTE: The top timeline example works as you resize the browser. It is 100% width of the page (or containing element.)
How do i make the second timeline overflow correctly? It must take up the remaining width of the screen (no with: 100px hacks), and if possible only show scroll bars when the months overflow.
This is an internal application so I can tell people to use Firefox or Chrome if I need to. This means I can use advanced CSS3 stuff or browser specific ( -webkit or -moz ) stuff. I'd prefer that it was IE8 compatable (just for my own curiosity)
If you can fix the width of that text (in pixels or percents) use this solution:
table {
table-layout: fixed;
width: 100%;
}
td:first-child {
width: 100px; /* or width: 15%; */
}
Note that you can use a different selector for the text (like a class)
Possible solution....
The main issue may be that the "Site Navigation" cell is part of the scroll area.
table { display: block; }
Then assign the .wrap class to the table and remove the div encompassing the months.
Fiddle here
only tested in Chrome.
You could just put a width on the div.wrap, say 400px- that works and is just one line of code:-)