I have an md-card that consists of an md-header and scrollable md-card-content. As the scrollable content gets taller, the header gets smaller and smaller for some reason. The width of the card can change and the header can possibly wrap around to 2 or 3 lines so a min-height on the header isn't a solution. The problem exists in latest IE and Chrome, not FF.
Click The "Add 5 Rows" button a few times to see the header shrink
http://plnkr.co/edit/wgBKnXh7FSn1VLO8mST0?p=preview
<html>
<head>
<title>angular material</title>
<link rel="stylesheet" href="https://rawgit.com/angular/bower-material/master/angular-material.css">
</head>
<body ng-app="app" ng-controller="ctrl" layout="column" layout-fill>
<md-card style="height: 200px; width: 500px">
<md-card-header style="border-bottom: 1px solid grey">
<md-card-header-text>
<span class="md-title">Long Header Long Header Long Header Long Header Long Header Long Header Long Header Long Header </span>
</md-card-header-text>
</md-card-header>
<md-content-card style="overflow-y: auto" >
<ul>
<li ng-repeat="x in getArray() track by $index"></li>
</ul>
</md-content-card>
</md-card>
<button style="width: 200px" ng-click="addRows()">
Add 5 Rows
</button>
<!-- Angular Material Dependencies -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular-animate.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular-aria.js"></script>
<!-- Angular Material Javascript using RawGit to load directly from `bower-material/master` -->
<script src="https://rawgit.com/angular/bower-material/master/angular-material.js"></script>
<script>
var app = angular.module('app', ['ngMaterial']);
app.controller("ctrl", function($scope) {
$scope.rows = 0;
$scope.addRows = function() {
$scope.rows += 5;
};
$scope.getArray = function() {
return new Array($scope.rows);
};
});
</script>
</body>
</html>
You just need to move the fixed height declaration from md-card to md-content-card - Plunker
Markup
<md-card style="width: 500px">
<md-card-header style="border-bottom: 1px solid grey">
<md-card-header-text>
<span class="md-title">Long Header Long Header Long Header Long Header Long Header Long Header Long Header Long Header </span>
</md-card-header-text>
</md-card-header>
<md-content-card style="height: 200px; overflow-y: auto" >
<ul>
<li ng-repeat="x in getArray() track by $index"></li>
</ul>
</md-content-card>
</md-card>
Related
I followed the example code here to put a dismissible drawer under a top app bar but it doesn't work.
Here is what I tried:
// Note: these styles do not account for any paddings/margins that you may need.
body {
display: flex;
height: 100vh;
}
.mdc-drawer-app-content {
flex: auto;
overflow: auto;
position: relative;
}
.main-content {
overflow: auto;
height: 100%;
}
.app-bar {
position: absolute;
}
// only apply this style if below top app bar
.mdc-top-app-bar {
z-index: 7;
}
<!doctype html>
<html lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Default Page Title</title>
<link rel="stylesheet" type="text/css" href="drawer.css">
<!--[if lt IE 9]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Test</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:400,500,700,900&display=swap">
<link rel="stylesheet" href="https://unpkg.com/material-components-web#4.0.0/dist/material-components-web.min.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<link rel="stylesheet" href="./drawer.css">
</head>
<header class="mdc-top-app-bar app-bar" id="app-bar">
<div class="mdc-top-app-bar__row">
<section class="mdc-top-app-bar__section mdc-top-app-bar__section--align-start">
<button class="mdc-top-app-bar__navigation-icon mdc-icon-button material-icons" href="#">menu</button>
<span class="mdc-top-app-bar__title">Dismissible Drawer</span>
</section>
</div>
</header>
<aside class="mdc-drawer mdc-drawer--dismissible mdc-top-app-bar--fixed-adjust">
<div class="mdc-drawer__content">
<div class="mdc-list">
<a class="mdc-list-item mdc-list-item--activated" href="#" aria-current="page">
<i class="material-icons mdc-list-item__graphic" aria-hidden="true">inbox</i>
<span class="mdc-list-item__text">Inbox</span>
</a>
<a class="mdc-list-item" href="#">
<i class="material-icons mdc-list-item__graphic" aria-hidden="true">send</i>
<span class="mdc-list-item__text">Outgoing</span>
</a>
<a class="mdc-list-item" href="#">
<i class="material-icons mdc-list-item__graphic" aria-hidden="true">drafts</i>
<span class="mdc-list-item__text">Drafts</span>
</a>
</div>
</div>
</aside>
<div class="mdc-drawer-app-content mdc-top-app-bar--fixed-adjust">
<main class="main-content" id="main-content">
App Content
</main>
</div>
<body>
<script src="https://unpkg.com/material-components-web#4.0.0/dist/material-components-web.min.js"></script>
<script>
// Instantiate MDC Drawer
const drawerEl = document.querySelector('.mdc-drawer');
const drawer = new mdc.drawer.MDCDrawer.attachTo(drawerEl);
// Instantiate MDC Top App Bar (required)
const topAppBarEl = document.querySelector('.mdc-top-app-bar');
const topAppBar = new mdc.topAppBar.MDCTopAppBar.attachTo(topAppBarEl);
topAppBar.setScrollTarget(document.querySelector('.main-content'));
topAppBar.listen('MDCTopAppBar:nav', () => {
drawer.open = !drawer.open;
});
</script>
</body>
</html>
In order to have the header on the side of the dismissble drawer, you need the following structure:
// Instantiate MDC Drawer
const drawerEl = document.querySelector('.mdc-drawer');
const drawer = new mdc.drawer.MDCDrawer.attachTo(drawerEl);
// Instantiate MDC Top App Bar (required)
const topAppBarEl = document.querySelector('.mdc-top-app-bar');
const topAppBar = new mdc.topAppBar.MDCTopAppBar.attachTo(topAppBarEl);
topAppBar.setScrollTarget(document.querySelector('.main-content'));
topAppBar.listen('MDCTopAppBar:nav', () => {
drawer.open = !drawer.open;
});
// Note: these styles do not account for any paddings/margins that you may need.
body {
display: flex;
height: 100vh;
}
.mdc-drawer-app-content {
flex: auto;
overflow: auto;
position: relative;
}
.main-content {
overflow: auto;
height: 100%;
}
.app-bar {
position: absolute;
}
// only apply this style if below top app bar
.mdc-top-app-bar {
z-index: 7;
}
<!-- IMPORTS -->
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css">
<link rel="stylesheet"
href="https://fonts.googleapis.com/css?family=Roboto:400,500,700,900&display=swap">
<link rel="stylesheet"
href="https://unpkg.com/material-components-web#4.0.0/dist/material-components-web.min.css">
<link rel="stylesheet"
href="https://fonts.googleapis.com/icon?family=Material+Icons">
<!-- CONTENT -->
<aside class="mdc-drawer mdc-drawer--dismissible">
<div class="mdc-drawer__content">
<div class="mdc-list">
<a class="mdc-list-item mdc-list-item--activated"
href="#"
aria-current="page">
<i class="material-icons mdc-list-item__graphic"
aria-hidden="true">inbox</i>
<span class="mdc-list-item__text">Inbox</span>
</a>
<a class="mdc-list-item"
href="#">
<i class="material-icons mdc-list-item__graphic"
aria-hidden="true">send</i>
<span class="mdc-list-item__text">Outgoing</span>
</a>
<a class="mdc-list-item"
href="#">
<i class="material-icons mdc-list-item__graphic"
aria-hidden="true">drafts</i>
<span class="mdc-list-item__text">Drafts</span>
</a>
</div>
</div>
</aside>
<div class="mdc-drawer-app-content">
<header class="mdc-top-app-bar app-bar"
id="app-bar">
<div class="mdc-top-app-bar__row">
<section class="mdc-top-app-bar__section mdc-top-app-bar__section--align-start">
<button class="mdc-top-app-bar__navigation-icon mdc-icon-button material-icons"
href="#">menu</button>
<span class="mdc-top-app-bar__title">Dismissible Drawer</span>
</section>
</div>
</header>
<main class="main-content"
id="main-content">
App Content
</main>
</div>
<!-- IMPORTS -->
<script src="https://unpkg.com/material-components-web#4.0.0/dist/material-components-web.min.js"></script>
Changes to make this work:
First, you don't need the class mdc-top-app-bar--fixed-adjust since we won't need to adjust the items anymore
Next, move the header itself into the app content (here, called mdc-drawer-app-content).
I looked at this example's HTML in order to see how they did it themselves
Here is the custom CSS that worked for me. Mine is a permanent drawer, so you may need some JS to apply the changes dynamically if you want the drawer to be dismissible, but it solves the layout issues.
First, the critical bit:
.mdc-drawer {
position: fixed;
top: 64px;
}
Since the drawer is now fixed-position, it no longer affects the layout, and the top bar sees it has room to fill the whole width of the page. Pushing the drawer down 64 px keeps it from covering the top bar.
However, this has some side-effects that have to be dealt with. First, most obviously, your main content does the same thing the top bar does--it thinks it has room to fill the whole page, so it gets lost behind the drawer. This is fixable by simply pushing it over:
main {
margin-left: 255px;
}
Second, you will notice that if you resize the viewport, the drawer doesn't show a scroll bar when it should, and when the scroll bar does appear, it won't go all the way to the bottom. This is because you've pushed the bottom of the drawer down off the page.
To fix this, make the drawer's scrollable content shorter:
.mdc-drawer__content {
height: calc(100% - 128px);
}
(I would have expected it to be 100% - 64px, but for some reason it needs 128. I haven't figured out why.)
TODO: Create an AngularJS directive to display list of images in an endless, smooth left to right scrolling loop. To keep it simple you can assume the fixed height/width for the images indicated above.the work should be done in the directive and styles without adding supporting libraries or plugins.
angular.module('myApp', [])
.controller('myCtrl', function ($scope) {
// list of images to scroll, each image is 280px x 200px
$scope.images = [
'http://build.ford.com/dig/Ford/Mustang/2018/BP3TT-TILE-EXT/Hero/EXT/4/vehicle.png',
'http://build.ford.com/dig/Ford/Mustang/2018/BP3TT-TILE-EXT/Hero[EcoBoost®%20Fastback]/EXT/4/vehicle.png',
'http://build.ford.com/dig/Ford/Mustang/2018/BP3TT-TILE-EXT/Hero[EcoBoost® Premium Fastback]/EXT/4/vehicle.png',
'http://build.ford.com/dig/Ford/Mustang/2018/BP3TT-TILE-EXT/Hero[EcoBoost® Convertible]/EXT/4/vehicle.png',
'http://build.ford.com/dig/Ford/Mustang/2018/BP3TT-TILE-EXT/Hero[GT Fastback]/EXT/4/vehicle.png',
'http://build.ford.com/dig/Ford/Mustang/2018/BP3TT-TILE-EXT/Hero[GT Premium Convertible]/EXT/4/vehicle.png',
'http://build.ford.com/dig/Ford/Mustang/2018/BP3TT-TILE-EXT/Hero[Shelby® GT350R]/EXT/4/vehicle.png',
'http://build.ford.com/dig/Ford/Mustang/2018/BP3TT-TILE-EXT/Hero[Shelby GT350®]/EXT/4/vehicle.png'];
})
.directive('myScroller', function () {
return {
// >> your directive code <<
};
});
.container {
width: 700px;
margin: 0 auto 100px;
padding: 20px;
overflow: hidden;
}
.container .image-list {
height:200px;
width:2240px;
}
<!DOCTYPE html>
<html>
<head>
<script data-require="angular.js#1.1.5" data-semver="1.1.5" src="http://code.angularjs.org/1.1.5/angular.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body>
<div ng-app="myApp">
<div ng-controller="myCtrl">
<div class="container">
<h1>Static Images</h1>
<div class="image-list">
<img ng-repeat="image in images" ng-src="{{image}}" />
</div>
</div>
<div class="container">
<h1>Scrolling Images</h1>
<!-- use my scroller directive, see script.js file for directions -->
<div my-scroller="images"></div>
</div>
</div>
</div>
</body>
</html>
I wanted to build a simple template like Youtube with angular material.
But I am kinda stuck with a sidebar navigation issue. The following should be possible in the template
1. The sidebar should be opened on load (depending on the size of the screen)
2. If the browser is resized, the sidebar should autohide/show
3. If the menu button on the top-left is clicked, the sidebar should toggle as a part of the page (and not an overlay). It can be an overlay only when the screensize is small enough.
The menu button in the navigation bar and the sidebar are in different controllers. So I have written a factory to share the click event and its outcome
The html code for the html is as below
<html>
<head>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet" />
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/angular_material/1.1.0/angular-material.min.css" />
<style>
.add-vertical-shadow{
-webkit-box-shadow: 0px 4px 18px 0px rgba(0,0,0,0.75);
-moz-box-shadow: 0px 4px 18px 0px rgba(0,0,0,0.75);
box-shadow: 0px 4px 18px 0px rgba(0,0,0,0.75);
}
</style>
<!-- Angular Material requires Angular.js Libraries -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-animate.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-aria.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-messages.min.js"></script>
<!-- Angular Material Library -->
<script src="https://ajax.googleapis.com/ajax/libs/angular_material/1.1.1/angular-material.min.js"></script>
<!-- User js files here -->
<script src="main.js"></script>
<script>
</script>
</head>
<body ng-app="mainApp" layout="column">
<div ng-cloak="" class="toolbardemoBasicUsage" layout="column">
<md-toolbar class="md-hue-2 add-vertical-shadow" ng-controller="navCtrl">
<div class="md-toolbar-tools">
<md-button class="md-icon-button" aria-label="menu" ng-click="toggleClicked()">
<md-icon aria-label="Menu" class="material-icons">menu</md-icon>
</md-button>
<h2 flex="" md-truncate="">MyApp</h2>
<md-button class="md-icon-button" aria-label="more_vert">
<md-icon aria-label="more_vert" class="material-icons">more_vert</md-icon>
</md-button>
</div>
</md-toolbar>
<!-- this will contain the main body and the sidebar -->
<md-content flex >
<div layout="vertical" ng-controller="sidebarCtrl" layout-fill>
<!-- Sidebar start -->
<md-sidenav class="md-sidenav-left md-whiteframe-4dp" md-component-id="leftSideBar" md-is-locked-open="{{hide}}">
<form>
<md-input-container>
<label for="testInput">Test input</label>
<input id="testInput" type="text" ng-model="data" />
</md-input-container>
</form>
</md-sidenav>
<!-- Sidebar end -->
<!-- Main Body start -->
<md-content flex layout-padding>
Main body
</md-content>
<!-- Main Body end -->
</div>
</md-content>
</div>
</body>
</html>
and the js file
var mainApp = angular.module('mainApp',['ngMaterial']);
mainApp.factory('toggleSidebar', function($mdSidenav, $mdMedia){
return {
hide : $mdMedia('gt-xs'),
toggle : function(sidebarElement){
$mdSidenav(sidebarElement).toggle();
this.hide = !this.hide;
}
};
});
mainApp.controller('navCtrl', function($scope, toggleSidebar) {
$scope.toggleClicked = function(){
toggleSidebar.toggle('leftSideBar');
console.log('hide : ' + toggleSidebar.hide);
}
});
mainApp.controller('sidebarCtrl', function($scope, toggleSidebar) {
$scope.hide = toggleSidebar.hide;
});
Any help is greatly appreciated.
The problem was, "Any changes in the service parameter wasn't reflecting sidebarCtrl controller."
I can't pinpoint the reason, but the bonding somehow wasn't 2-way, although I expected it to be
The below code helped
mainApp.controller('sidebarCtrl', function($scope, toggleSidebar) {
$scope.hide = function(){
return toggleSidebar.hide;
};
});
I have got the following sample html.
Files variable is a simple array of integers, like [1,2,3,4,5,6]
<!doctype html>
<html ng-app="Application">
<head>
<title></title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js"></script>
<!--<script src="../app.js"></script>
<script src="../Controller/applicationCtrl.js"></script>-->
<script>
var app = angular.module('Application', []);
var applicationCtrl = function ($scope) {
$scope.files = [1,2,3,4,5,6];
$scope.showAll = false;
};
app.controller('vm', applicationCtrl);
</script>
<style>
.J1 {
overflow-y: scroll;
height: 70px;
}
</style>
</head>
<body ng-controller="vm">
<div style="width: 100px;" ng-class="{'J1': (files.length > 3) && !showAll}">
<div ng-repeat="file in files" style="border-width: 1px; border-style: solid;">
<span>{{file}}</span>
<input type="button" value="{{'btn' + file}}"></input>
</div>
</div>
<br />
<div>
<a href ng-click="showAll = !showAll;">Show {{ showAll ? 'less':'more'}}</a>
</div>
</body>
</html>
If the length of files array is more than 3 then it adds the overflow css to the div. But I also set the height of the div to a fixed value. What I would like to do is to set the height of div based on the heights of the first 3 divs on the fly without setting a fixed value for it. How can I achieve this?
You may try this. I've added jquery CDN. You can do this with raw javascript though.
<!doctype html>
<html ng-app="Application">
<head>
<title></title>
<script src="https://code.jquery.com/jquery-2.2.3.min.js" integrity="sha256-a23g1Nt4dtEYOj7bR+vTu7+T8VP13humZFBJNIYoEJo=" crossorigin="anonymous"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js"></script>
<script>
var app = angular.module('Application', []);
var applicationCtrl = function ($scope) {
$scope.files = [1,2,3,4,5,6];
/* Set the parent div's height */
$(function(){
$('.J1').height($('.each-button').outerHeight() * 3);
});
};
app.controller('vm', applicationCtrl);
</script>
<style>
.J1 {
overflow-y: scroll;
}
</style>
</head>
<body ng-controller="vm">
<div style="width: 100px;" class="J1">
<!-- new class has been added -->
<div class="each-button" ng-repeat="file in files" style="border-width: 1px; border-style: solid;">
<span>{{file}}</span>
<input type="button" value="{{'btn' + file}}"></input>
</div>
</div>
<br />
<div>
<a href>Show more</a>
</div>
</body>
</html>
I'm new to Blogger, and HTML and am trying to set up a fashion-blogging website on Blogger.
I've been successful in making the header image static (that is, doesn't move when scrolling through posts), but unfortunately it isn't aligned at the very top of the website. This makes it look very odd as content disappears as it scrolls under the header image, and reappears briefly as it scrolls between the header image and top of page.
I've looked into some basic HTML, but there is a huge jump from basic HTML to the HTML I see when I try to edit HTML directly on my Blogger website. I just want the header image to be aligned at the very top.
Can anyone help? Anything is appreciated.
Add the css top:0 to the DIV with ID "header-outer"
Plus
Why do you have so much unnecessary markup? You could replace all of this:
<div class="header-outer">
<div class="header-cap-top cap-top">
<div class="cap-left"></div>
<div class="cap-right"></div>
</div>
<div class="fauxborder-left header-fauxborder-left">
<div class="fauxborder-right header-fauxborder-right"></div>
<div class="region-inner header-inner">
<div id="header" class="header section"><div id="Header1" class="widget Header">
<div id="header-inner">
<a style="display: block" href="http://monsemble.blogspot.ca/">
<img width="833px; " height="216px; " style="display: block" src="http://2.bp.blogspot.com/-91QDCMg_EsU/UcsYVdMvLQI/AAAAAAAAACw/Oa727KfuuBk/s1600/header.jpg" id="Header1_headerimg" alt="MONSEMBLE">
</a>
</div>
</div>
</div>
</div>
</div>
<div class="header-cap-bottom cap-bottom">
<div class="cap-left"></div>
<div class="cap-right"></div>
</div>
</div>
With:
<div class="header-outer">
<a style="display: block" href="http://monsemble.blogspot.ca/">
<img width="833px; " height="216px; " style="display: block" src="http://2.bp.blogspot.com/-91QDCMg_EsU/UcsYVdMvLQI/AAAAAAAAACw/Oa727KfuuBk/s1600/header.jpg" id="Header1_headerimg" alt="MONSEMBLE">
</a>
</div>
I faced something similar on my Blogger blog and I noticed that inspite of me switching off the navbar that comes with the Blogger website, in the the HTML code there was still a division on the top of the page for the navbar. I removed it from the template and was able to move the header image to the top of the webpage.
I removed this section of the code -
<b:section class='navbar' id='navbar' maxwidgets='1' showaddelement='no'>
<b:widget id='Navbar1' locked='true' title='Navbar' type='Navbar'>
<b:includable id='main'><script type="text/javascript">
function setAttributeOnload(object, attribute, val) {
if(window.addEventListener) {
window.addEventListener('load',
function(){ object[attribute] = val; }, false);
} else {
window.attachEvent('onload', function(){ object[attribute] = val; });
}
}
</script>
<div id="navbar-iframe-container"></div>
<script type="text/javascript" src="https://apis.google.com/js/plusone.js"></script>
<script type="text/javascript">
gapi.load("gapi.iframes:gapi.iframes.style.bubble", function() {
if (gapi.iframes && gapi.iframes.getContext) {
gapi.iframes.getContext().openChild({
url: 'https://www.blogger.com/navbar.g?targetBlogID\0752197236978911214706\46blogName\75MahekMody.com\46publishMode\75PUBLISH_MODE_HOSTED\46navbarType\75DISABLED\46layoutType\75LAYOUTS\46searchRoot\75http://www.mahekmody.com/search\46blogLocale\75en\46v\0752\46homepageUrl\75http://www.mahekmody.com/\46vt\0753008633957882384298',
where: document.getElementById("navbar-iframe-container"),
id: "navbar-iframe"
});
}
});
</script><script type="text/javascript">
(function() {
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = '//pagead2.googlesyndication.com/pagead/js/google_top_exp.js';
var head = document.getElementsByTagName('head')[0];
if (head) {
head.appendChild(script);
}})();
</script>
</b:includable>
</b:widget>
</b:section>