How to serve responsive images using srcset in a v-for loop with Vue.JS? - responsive-design

<div class="image-thumbnail--hero">
<img :src="project.thumbnails.small[0]"
:srcset="`${project.thumbnails.small[0]} 300w, ${project.thumbnails.medium[0]} 900w, ${project.thumbnails.high[0]} 1400w`"
sizes="(min-width: 768px) 70vw, (min-width: 1200px) 50vw, 300px"
width="100%"
:alt="project.title">
</div>
<div class="image-thumbnails">
<ul class="list-unstyled">
<li v-for="thumbnail in project.thumbnails.small" #click="swapThumbnail(thumbnail)">
<img class="lazy" :data-src-lazy="thumbnail" alt="thumbnail" width="100">
</li>
</ul>
</div>
Suppose I have these thumbnail images, different resolutions for different viewports.
thumbnails: {
small: [
'http://placehold.it/330x330',
'http://placehold.it/330x330',
'http://placehold.it/330x330'
],
medium: [
'http://placehold.it/900x900',
'http://placehold.it/900x900',
'http://placehold.it/900x900'
],
high: [
'http://placehold.it/1400x1400',
'http://placehold.it/1400x1400',
'http://placehold.it/1400x1400'
]
},
I want to loop set a set of images, and they should be responsive using srcset attribute. Right now I just loop through the small thumbnails:
<div class="image-thumbnails">
<ul class="list-unstyled">
<li v-for="thumbnail in project.thumbnails.small" #click="swapThumbnail(thumbnail)">
<img class="lazy" :data-src-lazy="thumbnail" alt="thumbnail" width="100">
</li>
</ul>
</div>
Is there a way to make it responsive? Just like the code inside image-thumbnail--hero?
The thumbnails inside image-thumbnails are small, like 100x100. When a user clicks one of the thumbnails, a higher resolution is shown in image-thumbnail--hero. When I didn't use responsive images, I had defined a method for doing this:
swapThumbnail(imgUrl) {
this.selectedThumbnail = imgUrl;
}
selectedThumbnail is supposed to bind to image-thumbnail--hero img, but since that part is now using responsive image, it's hard to make it work because I don't know which resolution of the image (small, medium, high) should I select and show.
To sum up, there are the 2 problems I find difficult to solve
show responsive images with v-for
show a high resolution image (hero image) when a user clicks the associated thumbnail.
The hero image and thumbnail images should both be responsive.
Any insight would be highly appreciated!

Related

How to center conent using React bootstrap

I'm trying to do the infamous center operation both vertical and horizontal and have sorta succeeded in doing so.
I'm trying to render a simple react component on my page that will show a 404 message. I want this message to be centered. The way I managed to do this some whitespace is leftover resulting in vertical scroll bars showing up. Ofc I could get rid of them using something like overflow-hidden, but surely there must be a way to center this message perfectly just using a better structure or certain bootstrap classes.
Here is my component:
const NotFoundPage = () => {
return (
<div>
<NavbarComp />
<div className="d-flex align-items-center justify-content-center text-center min-vh-100">
<div>
<h3 className="m-4">
<Badge variant="primary">404</Badge> Page not found...
</h3>
<Link to="/">
<Button variant="secondary">Go to main page</Button>
</Link>
</div>
</div>
</div>
);
};
In the end, I don't care that the scrollbars appear but it bothers me that this positional issue keeps occurring for me in some form or another and I wanna learn to put an end to this :)
You have already figured out how to center your "Not Found" message. What's messing it up for you is the Navbar, which you can test by taking it out. You will notice that the scroll bars disappear.
This class min-vh-100 gives the flex box below the Navbar the height of 100% of the viewport, which avoids adding any scrolls bars. The issue is that Navbar barges in and throw the page off blalance by attaching itself to the top. So the amount of srolling is exactly the height of the Navbar and since it's empty, there is very little scrolling.
An intutitive solution is to put your Navbar INSIDE the flex box. But that won't work in your case, because of how your flex box adjusts items. So I will give you a simpler solution, which should be viewed as more of a work-around.
Bootstrap does not come with classes such as min-vh-95 or min-vh-80, but luckily they are super easy to create. You can add this class to your custom CSS:
.not-found-container {
min-height: 95vh !important;
}
(or you could just stick to the naming convention and name it min-vh-95 for example)
And then change the flex box classes from:
<div className="d-flex align-items-center justify-content-center text-center min-vh-100">
to
<div className="d-flex align-items-center justify-content-center text-center not-found-container">
Here is a Sandbox to illustrate the idea: https://codesandbox.io/s/peaceful-sanne-e3m9w?file=/src/App.js
Obviously the min-height value would need to be adjusted based on the height if your Navbar.

Dynamic population of Bootstrap 4 carousel via Angular 4 not displaying images

I am trying to dynamically populate a Bootstrap 4 carousel via an ngFor iterating over an array of strings that contain the image urls. The carousel is not displaying the images, though looking at the markup generated everything looks fine. I'm guessing that the component is rendering before Angular is adding in the divs for each slide, as the "carousel slide" div has a height of 0px, which I think is what is hiding the slides themselves.
Behind-the-scenes I have an exposed property named "primarySlideshowImages" containing an array of urls:
ngOnInit() {
this.primarySlideshowImages = this.photoService.getImageLists(ImageListKeys.BrochureProductsPrimary);
}
The HTML markup looks like this:
<div id="carousel1" class="carousel slide" data-ride="carousel">
<div class="carousel-inner" role="listbox">
<div *ngFor="let image of primarySlideshowImages; let i = index" class="carousel-item {{ (i == 0) ? 'active' : ''}}">
<img class="d-block img-fluid w-100" [src]="image" >
</div>
</div>
<a class="carousel-control-prev" href="#carousel1" role="button" data-slide="prev"> <span class="carousel-control-prev-icon" aria-hidden="true"></span> <span class="sr-only">Previous</span> </a>
<a class="carousel-control-next" href="#carousel1" role="button" data-slide="next"> <span class="carousel-control-next-icon" aria-hidden="true"></span> <span class="sr-only">Next</span> </a>
FYI, I have tested this by hardcoding rather than dynamically adding the images, and everything renders just fine. I think it's a timing thing, but given my relative unfamiliarity with this technology I just don't know how to even search for a solution at this point.
Thank you in advance for your assistance. I do recognize that there are other components and approaches I could use - the ng-bootstrap components, open-source components, purchasable ones, etc. I'd like to try to figure this out using the bootstrap components because I'm pretty new at this technology and hate to jump to an easy solution if there is something I just don't understand that I should be doing. Thanks again for any help you may offer.
It may be that the div containing the image has a width and/or height of the div containing the image is/are 0.
Try setting a style on them. e.g .carousel-item {width:200px; height:200px;}
Also, try checking if the images are being retrieved by the browser using the Network tab on the dev tools.

Simple Materialize UI Responsive Side Menu

I've searched high and low for the Materialize UI equivalent of this (example in lighter weight MUI CSS): -
https://www.muicss.com/docs/v1/example-layouts/responsive-side-menu
For example on a desktop sould look like this (with ability to show / hide menu via burger icon): -
But on a mobile would look like this: -
I kept at it and came up with something using the documentation (http://materializecss.com/side-nav.html).
I've attached the HTML, CSS + JavaScript below if anyone is interested.
NOTE: In my answer there is no burger when viewed at a desktop size i.e. no ability to hide the menu. I discovered that if I removed the hide-on-large-only attribute on the following <a> then it put a menu over the top of the existing menu.
<i class="material-icons">menu</i>
Also, when clicking out of the menu it disappeared completely! :-)
Ideally it would be nice to have the burger in the desktop size so the menu can be hidnen if necessary but happy enough with this solution TBH.
$('.button-collapse').sideNav({
menuWidth: 300, // Default is 300
edge: 'left', // Choose the horizontal origin
closeOnClick: false, // Closes side-nav on <a> clicks, useful for Angular/Meteor
draggable: true // Choose whether you can drag to open on touch screens
});
#container {
padding-left: 300px;
}
#content {
padding: 20px;
}
#media only screen and (max-width : 992px) {
#container {
padding-left: 0px;
}
}
<!-- JQuery / Materialize CSS + JavaScript imports -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.98.0/css/materialize.min.css" rel="stylesheet" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.98.0/js/materialize.min.js"></script>
<!-- HTML -->
<div id="container">
<div id="menu">
<ul id="slide-out" class="side-nav fixed show-on-large-only">
<li>First Sidebar Link</li>
<li>Second Sidebar Link</li>
<li class="no-padding">
<ul class="collapsible collapsible-accordion">
<li>
<a class="collapsible-header">Dropdown<i class="material-icons">arrow_drop_down</i></a>
<div class="collapsible-body">
<ul>
<li>First</li>
<li>Second</li>
<li>Third</li>
<li>Fourth</li>
</ul>
</div>
</li>
</ul>
</li>
</ul>
</div>
<div id="content">
<i class="material-icons">menu</i>
<h3>Simple Materialize Responsive Side Menu</h3>
<p>Resize browser to see what it looks like in (a) brwoser (b) mobile devices</p>
</div>
</div>

How do I hide a div on mobile

I have the following landing page - Cold Call with Confidence
There are two downward facing arrows on the page that are generated with the code below:
<div class="content" style="padding-top:0px;">
<div class="right sld_cont">
<img src="http://coldcallwithconfidence.com/wp-content/uploads/2015/01/Arrow_comic_right_gray_T.png">
</div>
<div class="left sld_cont">
<img src="http://coldcallwithconfidence.com/wp-content/uploads/2015/01/Arrow_comic_right_gray_T1.png">
</div>
</div>
I would like to hide one of the arrows on mobile as it looks repetitive in the mobile view.
Can anyone explain how I might do that?
I would suggest that you are looking to hide the right arrow on viewports that stack those elements rather than specifically hiding them on mobile devices.
The previous answer is correct based upon your question, however I think this might be a more suitable solution for you.
#media only screen and (max-width: 679px) {
.right.sld_cont {
display: none;
}
}
This means that for any viewport that is 679px or smaller the right arrow will be hidden.
Take a look at MobileDetect.js , then you can use this as a PHP if statement, and only show it if it's not a mobile device.
if(!$detect->isMobile()) {
# desktop code
}
Edit:
<?php if(!$detect->isMobile()) { ?>
<div class="content" style="padding-top:0px;">
<div class="right sld_cont">
<img src="http://coldcallwithconfidence.com/wp-content/uploads/2015/01/Arrow_comic_right_gray_T.png">
</div>
<div class="left sld_cont">
<img src="http://coldcallwithconfidence.com/wp-content/uploads/2015/01/Arrow_comic_right_gray_T1.png">
</div>
</div>
<?php } ?>

Using Masonry in AngularJS / Bootstrap app

I have been trying (unsuccessfully) for the past two days to use Masonry in an app. My app uses AngularJS and Bootstrap. I need to display images in Bootstrap panels. The images will be dynamically loaded. Each panel will be 200px in size. I want the panels to get added left-to-right with a maximum of four columns. There is a demo on the official angular-masonry site that is similar to what I'm trying to do. They do not use panels though.
When my app runs, my panels always load vertically. There are no columns. Just one single column basically. I can't figure out why. I've created a JSFiddle here. The setup for the masonry stuff is pretty simple. It looks like this:
<masonry>
<div class="masonry-brick panel panel-default" ng-repeat="item in items">
<div class="panel-heading">
<h3 class="panel-title">{{item.title}}</h3>
</div>
<div class="panel-body">
<img ng-src="{{ item.imageUrl }}" alt="A masonry brick">
</div>
</div>
</masonry>
Can someone please tell me what I'm doing wrong? I worked all weekend on this. Thank you!

Resources