Angular 7 sticky footer with bootstrap4 - css

I'm learning angular7 and I would create a sticky footer. I've tried a lot of solutions.
I tried :
https://getbootstrap.com/docs/4.3/examples/sticky-footer-navbar/
some solution in stackoverflow
some solution found via google search (like this)
No one works for me. I don't understand why, and I need help.
I have this code after removing all I've tried:
app.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { MenuComponent } from './menu/menu.component';
import { FooterComponent } from './footer/footer.component';
#NgModule({
declarations: [
AppComponent,
MenuComponent,
FooterComponent,
],
imports: [
BrowserModule,
AppRoutingModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
index.html (just the body)
<!doctype html>
<html lang="en">
<head>
...
</head>
<body class="d-flex flex-column h-100">
<app-root></app-root>
</body>
</html>
app.component.html
<app-menu></app-menu>
<main class="container">
<router-outlet></router-outlet>
</main>
<div class="footer mt-auto py-3">
<app-footer></app-footer>
</div>
footer.component.html
<footer>
© 2019 - Zackna
</footer>
Edit: I update my codes with #avcajaraville answer that I have already tried but removed ^-^. And there is
my result, as you can see my footer is not sticky to the bottom of the page.
Is a bootstrap native solution exists? My footer does not have a definitive height. What do I need to do to achieve my goal?

Thanks to #avcajaraville for the answer.
Unfortunately, I missed the class h-100 when I tried it and I don't see i:/
In the meantime, I found a solution.
I added this CSS to my app-root component:
app-root {
height: 100vh;
display: flex;
flex-direction: column;
}
and a flex-grow: 1; to my container class.

According to your code samples, you are not adding the classes you need.
You can fix that by mimicking the same structure as in the example you provided:
index.html
<!doctype html>
<html lang="h-100">
<head>
...
</head>
<body class="d-flex flex-column h-100">
<app-root></app-root>
</body>
</html>
app.component.html
<app-menu></app-menu>
<main class="container">
<h1>title</h1>
<router-outlet></router-outlet>
</main>
<div class="footer mt-auto py-3">
<app-footer></app-footer>
</div>
I think this would give you the expected behavior.
In general, when working with a CSS framework, you need to use the classes specified in your html. Otherwise, no CSS can be applied.
EDIT
I added the needed class on the html tag in your index.html file & refactor app.component.html

Another way to do this if you want to just use the bootstrap utility classes and not write custom css using app-root's component css or custom css via :host
In your index.html do this,
<html class="h-100">
<head>....omitted</html>
<body class="h-100">
<app-root class="d-flex flex-column h-100"></app-root>
</body>
</html>
to recap, if you're following the sticky footer example from Bootstrap4 website using Angular then you need to put the utility class on app-root not the body and make sure just height of body element is set to 100% using h-100 (also need h-100 on html element as well!!)

This will always calculate the total height set the min-height for the content div for me the 202px was perfect.This will push the footer at the bottom.
.main-content {
min-height: calc(100vh - 202px);
}
<main>
<div class="main-content"></div>
<app-footer class="footer"></app-footer>
</main>

Related

I would like to know how to style bs5-lightbox

I hope someone can help a numpty :)
I am using Boostrap 5 and this Lightbox library https://trvswgnr.github.io/bs5-lightbox/
It uses data-toggle="lightbox" to initiate it and is working perfectly.
<a href="http://fpoimg.com/200x200?text=Forth" data-toggle="lightbox" data-gallery="gallery" >
<img src="http://fpoimg.com/200x200?text=Forth"></a>
I would like to apply some css styling eg. lightbox background-color, padding etc but I have no idea where to start.
I used to use the ekko-lightbox for BS4 which had its own CSS but I can't find one for this.
As I can see, bs5-lightbox library doesn't have it's own stylings, and using BS5 markups and stylings.
So you can apply BS5 stylings and HTML you want.
You can start by browsing .lightbox-carousel (CSS class selector) on your page and create custom styling.
Based on this class you can customize it's child nodes.
img {
width: 200px;
}
/* this is how you can add stylings to wrapper, f.e. */
.lightbox-carousel.carousel {
padding: 1rem;
background: #ffffff7a;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
<script type="module">
import * as Lightbox from 'https://cdn.jsdelivr.net/npm/bs5-lightbox#1.7.8/dist/index.bundle.min.js';
document.querySelectorAll('.my-lightbox-toggle').forEach((el) => el.addEventListener('click', (e) => {
e.preventDefault();
const lightbox = new Lightbox(el);
lightbox.show();
}));
</script>
<a href="https://unsplash.it/1200/768.jpg?image=251" data-toggle="lightbox">
<img src="https://unsplash.it/600.jpg?image=251" class="img-fluid my-lightbox-toggle">
</a>

Non-generated classname selector in css module

Let's say we have a third-party CardComponent like this
<Card title="This is a title in the header">This is text in the body</Card>
And this renders in plain HTML
<div class="Card">
<div class="CardHeader"></div>
<div class="CardBody"></div>
</div>
And I'm using css modules for styling (scss in this case).
.customCard {
.CardBody {
color: red;
}
}
And then add the class to Card
import styles from ...
...
<Card className={styles.customCard} ...>...</Card>
Above will not work because it creates a generated class for CardBody like CardBody_sjkdh43. Is there a way to select non generated classnames in modules? Or is this only possible in the old fashion way to use a stylesheet?
Demo SandBox
It's an old question but the answer is :global() selector in css modules.
For more info: Exceptions - CSS Modules
Example the code:
<div class={styles.myClass}>
<SomeComponentWithOwnCss />
</div>
Output:
<div class="myClass_s4jkdh3">
<div class="SomeComponentWithOwnCss"></div>
</div>
And CSS:
.myClass div:global(.SomeComponentWithOwnCss) {
background-color: red;
}
Working example overhere: codesandbox
a small addition to #Closery's answer, you saved my ass man❤️.
you could try this for a more convenient approach with SCSS:
.parent :global {
.non-cssmodule-class {
color: red;
}
}
<div className={styles.parent}>
<div className="non-cssmodule-class" />
</div>
output:
<style>
.filename-parent__7MR41 .non-cssmodule-class { color: red; }
</style>
<div class="filename-parent__7MR41">
<div class="non-cssmodule-class"></div>
</div>

haw i can adapt dhtmlxGantt display screen with my component?

i use dhtmlxGantt because i need gantt diagram in my project but i have a desplay problem . i use vuejs component that's why i put the code of dhtmlxGantt in my component but the display isn't clear
this is my code :
//Gantt component
<template>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-body">
<div id="gantt_here">
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
created(){
gantt.init("gantt_here");
},
mounted() {
console.log('Component mounted.')
}
}
</script>
<style scoped>
body{
margin: 10px ;
}
</style>
and i call this two file
<script src="https://cdn.dhtmlx.com/gantt/edge/dhtmlxgantt.js"></script>
<link href="https://cdn.dhtmlx.com/gantt/edge/dhtmlxgantt.css" rel="stylesheet">
please i need help
VueJS is very complicated when it comes to javascript components external to the components, what I can advise you in this case is to do the internal import of the component's library and try to use it, as I never used this component, so I don't know if it uses jQuery, but there are ways to use jQuery in VueJS.
An example of how you would use it would be installing the library using the command npm install --save #types/dhtmlxgantt, and importing it into your component.
<script>
import gantt from '#types/dhtmlxgantt'
export default {
...
created() {
gantt.init("gantt_here");
}
}
</script>

I have a plunker. When I define my css globally, it works. When I define my css in my component, it fails. What's going on?

With reference to this plunker:
https://plnkr.co/edit/GWsbdDWVvBYNMqyxzlLY?p=preview
I have the same css specified in the styles.css file, and in the src/app.ts file.
If I comment in the css in styles.css and comment out the css in src/app.ts, it works.
styles.css:
/* If these are commented in, and the ones in src/app.ts are
* commented out, the three items are spaced appropriately. */
/***
md-toolbar-row {
justify-content: space-between;
}
md-toolbar {
justify-content: space-between;
}
***/
If I comment out the css in styles.css and comment in the css in src/app.ts, it fails.
src/app.ts:
#Component({
selector: 'my-app',
template: `
<div>
<h2>Hello {{name}}</h2>
<md-toolbar color="primary">
<span><md-icon>mood</md-icon></span>
<span>Yay, Material in Angular 2!</span>
<button md-icon-button>
<md-icon>more_vert</md-icon>
</button>
</md-toolbar>
</div>
`,
// If these are commented in, and the ones in style.css are
// commented out, the three items are scrunched together.
/***/
styles: [
`md-toolbar-row {
justify-content: space-between;
}`,
`md-toolbar {
justify-content: space-between;
}`
]
/***/
})
export class App {
name:string;
constructor() {
this.name = `Angular! v${VERSION.full}`
}
}
I'm having trouble visualizing the difference between defining the css for the whole application, and for the specific component. Can someone tell me what's going on?
=================================
#bryan60 and #Steveland83 seem to indicate that the problem lies somewhere in the view encapsulation. And upon further investigation, it does in a sense.
If you look at the code below, you will see that the styles for md-toolbar and md-toolbar-row have an attribute attached. But the html for md-toolbar and md-toolbar-row does not match. Only md-toolbar has the attribute attached. md-toolbar-row doesn't. I have marked the relevant four lines with >>>>>.
So that's the problem but:
1. Do I report it to the material design people as an error?
2. Is there some workaround I can use today?
<html>
<head>
:
<script src="config.js"></script>
<script>
System.import('app')
.catch(console.error.bind(console));
</script>
<link href="https://rawgit.com/angular/material2-builds/master/prebuilt-themes/indigo-pink.css" rel="stylesheet">
<style>
>>>>> md-toolbar-row[_ngcontent-c0] {
justify-content: space-between;
}
</style>
<style>
>>>>> md-toolbar[_ngcontent-c0] {
justify-content: space-between;
}
</style>
<style>
.mat-toolbar {
display: flex;
: :
.mat-mini-fab,
.mat-raised-button {
outline: solid 1px
}
}
</style>
</head>
<body class="mat-app-background">
<my-app _nghost-c0="" ng-version="4.4.0-RC.0">
<div _ngcontent-c0="">
<h2 _ngcontent-c0="">Hello Angular! v4.4.0-RC.0</h2>
>>>>> <md-toolbar _ngcontent-c0="" class="mat-toolbar mat-primary" color="primary" role="toolbar" ng-reflect-color="primary">
<div class="mat-toolbar-layout">
>>>>> <md-toolbar-row class="mat-toolbar-row">
<span _ngcontent-c0=""><md-icon _ngcontent-c0="" class="mat-icon material-icons" role="img" aria-hidden="true">mood</md-icon></span>
<span _ngcontent-c0="">Yay, Material in Angular 2!</span>
<button _ngcontent-c0="" class="mat-icon-button" md-icon-button=""><span class="mat-button-wrapper">
<md-icon _ngcontent-c0="" class="mat-icon material-icons" role="img" aria-hidden="true">more_vert</md-icon>
</span>
<div class="mat-button-ripple mat-ripple mat-button-ripple-round" md-ripple="" ng-reflect-trigger="[object HTMLButtonElement]" ng-reflect-centered="true" ng-reflect-disabled="false"></div>
<div class="mat-button-focus-overlay"></div>
</button>
</md-toolbar-row>
</div>
</md-toolbar>
</div>
</my-app>
</body>
</html>
One of the Angular features is View Encapsulation which basically means that you can define styles scoped only to a specific component without affecting any other components.
By default styles are scoped only for the component they are referenced in, but you can choose to override that to make them available globally by setting your components encapsulation to None.
E.g.
import { Component, ViewEncapsulation } from '#angular/core';
#Component({
selector: 'component-that-shares-styles',
templateUrl: './component-that-shares-styles.component.html',
styleUrls: ['./component-that-shares-styles.component.scss'],
encapsulation: ViewEncapsulation.None // <-- Set encapsulation here
})
*Note that you will need to import ViewEncapsulation from #angular/core
Okay, with help from #Steveland83 and #bryon60, I came to a definite answer. The Material Design people are aware of this problem. They have made a writeup.
https://github.com/angular/material2/blob/master/guides/customizing-component-styles.md
Here's their summary:
Styling other components
If your component has view encapsulation turned on (default), your component styles will only
affect the top level children in your template. HTML elements belonging to child components cannot
be targeted by your component styles unless you do one of the following:
Add the overriding style to you global stylesheet. Scope the selectors so that it only affects
the specific elements you need it to.
Turn view encapsulation off on your component. If you do this, be sure to scope your styles
appropriately, or else you may end up incidentally targeting other components elswhere in your
application.
Use a deprecated shadow-piercing descendant combinator to force styles to apply to all the child
elements. Read more about this deprecated solution in the
Angular documentation.
I don't want to use global css, or a deprecated solution. I guess I will style with classes, and not elements. If someone has a better idea, tell me!

How to use component variable within css / style tag in Angular 2?

How can I use component variables within style TAG in Angular 2?
I do have an Angular 2 component for my header which I like to color depending on a users setting. Thus I'd like to assign an background and font color. While I know how to to this with an attribute binding to an element, I couldn't figure out how to use in a style tag.
Using attribute binding for style works well, however this gets pretty anoying for several subelements, especially if they are nested within other sub components. [ngStyle]= attribute is also only working on a single element.
<header id="header" [style.background-color]="changeBackground()">
<div>
Some Text
Some Link
<subcomponent></subcomponent>
</div>
<div> ... a lot mor stuff </div>
</header>
Thus I'd like to add something like
<style>
#header, #header a {
color: {{mycolor}};
}
</style>
to the html template. However this is not working
Similar Questions do not answer this question yet and only show attribute binding as a solution:
Angular2 dynamic change CSS property
Dynamically updating css in Angular 2
https://scotch.io/tutorials/all-the-ways-to-add-css-to-angular-2-components
https://coryrylan.com/blog/introduction-to-angular-2-ngclass-and-ngstyle
It looks to me like you are just creating a new component called 'subcomponent', why not do that?
subcomponent.ts:
import { Component } from '#angular/core';
#Component({
selector: 'subcomponent',
templateUrl: './subcomponent.html',
})
export class SubComponent {
mycolor = 'blue';
}
subcomponent.html:
<style>
#header, #header a {
color: {{mycolor}};
}
</style>
To your #Component object, add
styles:[ `#header, #header a {
color: {{mycolor}};
}`]
So for example:
#Component({
template: `<header id="header" [style.background-color]="changeBackground()">
<div>
Some Text
Some Link
<subcomponent></subcomponent>
</div>
<div> ... a lot mor stuff </div>
</header>`,
styles: [ `#header, #header a {
color: {{mycolor}};
}`
`]
})
Use NgStyle as explained in this answer
https://stackoverflow.com/a/41903349
in short
<header id="header" [ngStyle]="getStyle()">
<div>
Some Text
Some Link
<subcomponent></subcomponent>
</div>
<div> ... a lot mor stuff </div>
</header>
and
getStyle(): any {
return {"background-color" : this.changeBackgroundColor()};
}

Resources