Twitter Bootstrap 3 - Panels of Equal Height in a Fluid Row - css

I am new to Bootstrap 3 and I would like to have 3 panels on my landing page of equal height, even though the middle panel has less content. When resized they become the same height, but are not upon initial visit to the page.
I already tried hiding the overflow with CSS and it cuts off the bottom of the panel which isn't what I want, so I'm thinking I need to use jQuery.
Here is my code:
<div class="row-fluid">
<!--begin panel 1 -->
<div class="col-md-4">
<div style="text-align:center" class="panel panel-primary">
<div class="panel-heading">
<h1 class="panel-title text-center">Web y Metrícas</h1>
</div>
<!-- end panel-heading -->
<div class="panel-body">
<p>
<img style="margin: 0 auto;" class="img-responsive" src="web.png" height="30%" width="30%" alt="Web y Metrícas" />
</p>
<p class="text-left lead2">Apoyamos estratégicamente la presencia de tu empresa en el mundo digital, a través de la construcción de recursos web atractivos para tus clientes.</p>
<ul class="text-left">
<li>Web Corporativas</li>
<li>Tiendas Virtuales</li>
<li>Plataformas e-Learning</li>
<li>Arquitectura de Información</li>
<li>Google Analytics, SEO–SEM</li>
<li>Análisis de Competencia Digital</li>
<li>Data Mining</li>
</ul> <a class="btn btn-primary" href="#">Ver más »</a>
</div>
<!-- end panel-body -->
</div>
<!-- end panel-primary -->
</div>
<!--end col-md-4 -->
<!-- begin panel 2 -->
<div class="col-md-4">
<div style="text-align:center" class="panel panel-primary">
<div class="panel-heading">
<h1 class="panel-title">Gestíon de Redes Socials</h1>
</div>
<!-- end panel-heading -->
<div class="panel-body">
<p>
<img style="margin: 0 auto;" class="img-responsive" src="redes.png" height="30%" width="30%" alt="Gestíon de Redes Socials" />
</p>
<p class="text-left lead2">Crear una experiencia de marca excepcional a través de redes es más inteligente, rápida y las comunicaciones sociales serán más eficientes.</p>
<ul class="text-left">
<li>Compromiso</li>
<li>Publicación</li>
<li>Monitoreo</li>
<li>Analítica</li>
<li>Colaboración</li>
<li>CRM</li>
<li>Movil</li>
</ul> <a class="btn btn-primary" href="#">Ver más »</a>
</div>
<!-- end panel-body -->
</div>
<!-- end panel-primary -->
</div>
<!-- end col-md-4 -->
<!--begin panel 3 -->
<div class="col-md-4">
<div style="text-align:center" class="panel panel-primary">
<div class="panel-heading">
<h1 class="panel-title">Plan de Medios</h1>
</div>
<!-- end panel-heading -->
<div class="panel-body">
<p>
<img style="margin: 0 auto;" class="img-responsive" src="medios.png" height="30%" width="30%" alt="Plan de Medios" />
</p>
<p class="text-left lead2">Trabajamos en conjunto con la empresa para reforzar las fortalezas de su organización y las comunicamos de forma integral y con un mensaje claro.</p>
<ul class="text-left">
<li>Asesoría Comunicacional</li>
<li>RR.PP</li>
<li>Presencia de Marca</li>
<li>Clipping Digital</li>
<li>Manejo de Crisis</li>
<li>Lobby</li>
<li>Media Training</li>
</ul> <a class="btn btn-primary" href="#">Ver más »</a>
</div>
<!-- end panel-body -->
</div>
<!-- end panel-primary -->
</div>
<!-- end col-md-4 -->
</div>
<!-- end row -->

This can be done with CSS flexbox. Only minimal CSS is needed..
.equal {
display: -webkit-flex;
display: flex;
}
Just add .equal to your .row and flexbox does the rest.
http://www.codeply.com/go/BZA25rTY45
UPDATE: Bootstrap 4 uses flexbox so there is no need for the additional CSS.
http://www.codeply.com/go/0Aq0p6IcHs

Bootstrap's solution - add this css and add the class to your row:
.row-eq-height {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}
It has a couple caveats, as posted at http://getbootstrap.com.vn/examples/equal-height-columns/, but it sounds like it'll be good enough for your case.
I also saw this answer here.
Update for dynamic number of columns
Bootstrap automatically wraps columns into new rows when you add more than can fit in one row, but this flexbox approach breaks this. To get flexbox to wrap, I've found you can do something like this:
-webkit-flex-flow: row wrap;
flex-flow: row wrap;
-webkit-align-content: flex-end;
align-content: flex-end;
This is awesome when you have a dynamic number of columns, or columns that change width according to the screen size. So you can have something like this:
<div class="row row-eq-height">
<div class="col-sm-6 col-md-4">Content...</div>
<div class="col-sm-6 col-md-4">Content...</div>
<div class="col-sm-6 col-md-4">Content...</div>
<div class="col-sm-6 col-md-4">Content...</div>
<div class="col-sm-6 col-md-4">Content...</div>
</div>
And it all lines up the way it's expected. Just watch out - it only works in newer browsers. More info here

If you're going to use the bootstrap grid, I don't think you're going to find an easy way to accomplish this without hacks like the following css.
This basically says. When the screen width is greater than the md breakpoint in bootstrap, give all the elements with panel-body class which are direct descendants of the column elements a minimum height of 420px which happens to be a "magic number" that works with your existing content.
Again, I think this is a really gross solution, but it "works" in a pinch.
#media (min-width: 992px) {
.col-md-4 > .panel > .panel-body {
min-height: 420px;
}
}
Here's a CSS-Tricks article Fluid Width Equal Height Columns which covers various ways (display: table & flexbox) to accomplish this. However, you might need to step away from the responsive bootstrap grid for this particular task.
Also, here's the Complete Guide to Flexbox

Haven't found any of these CSS methods to work in my case I am using images in my panels too instead I used a simple JQuery function to get the job done
window.onload = function resizePanel(){
var h = $("#panel-2").height();
$("#panel-1").height(h); // add a line like this for each panel you want to resize
}
Where the ids "panel-1" and and "panel-2" are in the panel tag choose the largest panel as the one you use to set h and call the function at the end of you html.
<body onresize = "resizePanel()">
I also make it so the function is called when if the window is resized by adding the onresize attribute to the body

this function finds the largest .panel-body height, then makes that the height of all my .panel-body elements.
function evenpanels() {
var heights = []; // make an array
$(".panel-body").each(function(){ // copy the height of each
heights.push($(this).height()); // element to the array
});
heights.sort(function(a, b){return b - a}); // sort the array high to low
var minh = heights[0]; // take the highest number
$(".panel-body").height(minh); // and apply that to each element
}
Now that all the panel-bodys are the same, the heights need to be cleared when the window resizes before running the "evenpanels" function again.
$(window).resize(function () {
$(".panel-body").each(function(){
$(this).css('height',""); // clear height values
});
evenpanels();
});

I add top and bottom paddings in style for the lower <div>.
<div class="xxx" style="padding: 8px 0px 8px 0px">
...
</div>
Because after all each case is different and you have to adjust according to the situation.
Chrome dev tool can be very useful in situations like this.

Related

how to make an image use full height of it's parent in materialize Cards

I'm using materialize for my project, and I'm having a few problems with horizontal cards. The image I'm using has a height smaller than it's parent div so at the end of it, the background color is shown(problem image). I have tried to use max-width: 100% and max-height: 100% and nothing, also I tried to put the image as background-image in CSS instead of the img tag, but materialize hide the image if it doesn't detect the tag (problem with backgroung-image)
I know i should stretch an image, but its only a few px. And why i want to do this? bc it is ok if someone with a big screen sees it, but if i try to use a smaller screen, the text column on the right get taller, and the image stop covering the hole height of the row. This is what i want (image: how it should be)
Thanks for your time even if you didn't repy. Cheers from Chile.
Html code
<div class="col s12 m6 l4 offset-m3 options">
<div class="card">
<div class="topTitleCard"><h5 class="" >Opción 3 |</p></div>
<div class="card-image">
<img src="./content/araucaria_v2.jpg">
<div class="card-title">
<h4 class="white-text textShadow thicker-font">Viajando en el Bosque Milenario</h4>
</div>
<a rel="addtoCart" class="option3 btn-floating btn-large halfway-fab waves-effect waves-light mygreen" ><i class="material-icons">shopping_cart</i></a>
</div>
<div class="card-content">
<br>
<p>
Escoge el mirador que más te llene de paz, para que el día de mañana, puedán esparcir tus cenizas en el lugar que tu escogiste. Obten calma por siempre con el sonido del agua corriendo, o por el sonido de las copas de las Araucarias y Coihues moviendose por el viento.
Ver más...
</p>
</div>
<div>
<div class="card-tabs">
<h6 class="text-mygreen center-align">Ven y escoge tu vista para la eternidad:</h6>
<br>
<ul class="tabs tabs-fixed-width">
<li class="tab"><a class="whichTree active" value="1" href="#test3-1" style="color:#0F0F0F;">Mirador</a></li>
</ul>
</div>
<div class="card-content mygreen white-text myTabsCards">
<div id="test3-1">
<p>10 UF</p>
<a class="option3 waves-effect waves-light btn buyBtn" rel="addtoCart">Comprar</a>
</div>
<div class="bottomTabsPrices">
*precios validos hasta el 31/12/2019
</div>
</div>
</div>
</div>
</div>
CSS code (don't think is going to be useful, but here it's anyway):
.card-image{
margin-top:50px !important;
position: relative;
background-color: rgba(84,115,93,.5);
}
.card-image img{
max-width: 100%;
max-height:100%;
}
On your image put this css
width: 100%;
height: 100%;
object-fit:cover;
When using object-fit on image, you need to give it width and height properties. It won't work with max-width and max-height if width and height are not specified too.
It will always fill the parent of an image. It might cut it on sides but this depends of aspect ratio of image and parent.

How to divide *ngFor list of values into two divs

IN angular How to divide *ngFor list of columns into two side by side divs.
set1=[1,2,3,4,5,6.....]
<div *ngFor="let person of set2">{{person }}</div>
html
<div *ngFor="let person of set1; let ind = index;">
<div *ngIf="ind % 2 == 0">
{{set1[ind]}} - {{set1[ind+1]}}
</div>
</div>
ts
export class AppComponent {
set1 = [1,2,3,4,5,6];
}
try this -
<div *ngFor="let person of set1; let i = index">
<div *ngIf='i%2 === 0'>Even {{person}}</div>
<div *ngIf='i%2 !== 0'>Odd {{person}}</div>
</div>
Working Example
<div fxLayout="row" *ngFor="let person of set2; let i = index;" >
<div fxFlex="50%" *ngIf="i<set2.length/2">
{{person}}
</div>
<div fxFlex="50%" *ngIf="i>=set2.length/2">
{{person}}
</div>
</div>
You can also try if you know true condition...
<div *ngFor="let person of set1; let i = index">
<div *ngIf="true-condition;else notTrue">IF {{person}}</div>
<ng-template #notTrue>
<div>Else {{person}}</div>
</ng-template>
</div>
https://stackoverflow.com/a/58027002/10396570
Easy way: I am making the Angular demo Tour of Heroes and i wanted to divide in two columns the dashboard data *ngFor display;(like this) by ngFor
this is code it works for me right now:
<!--repeater creates as many links as
are in the component's heroes array.-->
<a *ngFor="let hero of heroes;" routerLink="/detail/{{hero.id}}">
<!--ESTE STYLE SIRVE PARA QUE NO SE DEMADRE EL TAMAÑO DE CADA
DIV, ELLIPSIS AYUDA EN ESTO-->
<div style="
width: 50%;
float: left;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;"
class="module hero">
{{hero.name}}
</div>
</a>

Put md-switch in the middle of the cards (AngularJS material design ,Css)

I want to create the same design like chrome settings page
https://www.pcworld.com/article/3162716/software/how-to-switch-to-chromes-material-design-settings-page-for-an-easier-experience.html
I do not manage to put the md-switch at the right and in static position like chrome settings
I do manage to put the md-switch in right to the title but I need it always in the middle of the card stick to right.
Image of my result: (current design)
<md-card md-theme="{{ showDarkTheme ? 'dark-purple' : 'default' }}" md-theme-watch>
<div class="option-item">
<div class="option-item-header">
<div class="option-item-header-title">
title
</div>
</div>
<div class="clear"></div>
<div class="option-body">
<p>text</p>
</div>
</div>
<div class="option-switch">
<md-switch ng-model="vm.model" aria-label="active" ng-change="function()">
</md-switch>
</div>
</md-card>

How can a scrollbar be triggered /using overflow property in an angular app (by ng-repeating through elements)?

I have a sidebar in my angular app and I am trying to make one div insight the sidebar scoll through the items and the content in the following div keep the same position (no scrolling). I have been looking at so many similar posts and tried everything but it just wont work. The problem is that either can you scroll through everything in the sidebar or not at all or that the bottom stayed (without moving) but then i the scrollbar was there for EACH item (and not for all items).
I used ng-repeat to put items on scope of the sidebar - is it perhaps different with angular that with reg. html?
Thanks!!
Ps. Im using gulp and the sidbar is a directive which I didnt include here. If anything is of importance, please let me know and I include it.
<li>
<a ng-click="openNav()"><i id="cart-icon" class="medium material-icons icon-design">shopping_cart</i></a>
<div id="mySidenav" class="sidenav closebtn" click-anywhere-but-here="closeNav()" ng-click="closeNav()">
<div class="sidebarBox">
<h2 class="sideBarHeader">Cart </h2>
<div class="sidebarContainer" ng-repeat="item in cart">
<img src="{{item.imageUrl}}" style="width:90px;height:100px;">
<div class="sidebarContent">
<p class="sidebarTitle">{{item.title}} </p>
<p class="sidebarSubtitle">Quality: {{item.quantity}}</p>
<p class="sidebarSubtitle">Price: ${{item.price}}</p>
</div>
<p class="sidebarLine"></p>
</div>
</div>
<br>
<div class="sidebarNoScroll">
<p style="color:black;font-size:22px;">Total</p>
<p class="sidebarTotal">${{ total() }}</p>
<button class="sidebarButtonContinueShopping" id='continue-shopping-button' ng-click="closeNav()">Continue Shopping</button>
<button class="sidebarButtonViewCart" ui-sref='cart' ng-click="closeNav()">View Cart</button>
</div>
</div>
</li>
css.
.sidebarContainer {
overflow:scroll;
height:224px;
}
.sidebarNoScroll {
overflow: hidden;
}
Wrap the container.
<div class="sidebarContainer">
<div ng-repeat="item in cart">
</div>
</div>

How to display unlimited items horizontally?

I have a list of items in one of my view.
I can only fit up to 6 items, and it's laid out like this:
I used class="col-md-2" for each one.
When I have more than 6, it just simply go down to the another row.
I don’t want that. You can see it here.
Now, if the list has 6 or more items,
list them horizontally
show the big > so that the users will know that there is more
show the 2 dots in the middle
Edit
This is what I got so far. I used Larval 4 so this syntax is in HTML/Blade.
#foreach ( MarketingMaterialCategory::all() as $mmc )
<h2><i class="fa fa-file-image-o color lighter"></i> {{{ $mmc->name or '' }}} <small> </small></h2>
<div class="row">
#foreach ( MarketingMaterial::where('marketing_materials_category_id','=', $mmc->id )->get() as $marketing_material)
<div class="col-md-2" >
<!-- Shopping items -->
<div class="shopping-item">
<!-- Image -->
<div class="col-sm-12 imgbox" >
<!-- <span class="col-sm-6"></span> -->
<img class="col-sm-12 pull-right" width="200" src="/marketing_materials/{{$marketing_material->id}}/download/thumb_path" alt="" />
</div>
<!-- Shopping item name / Heading -->
<h6>{{{ $marketing_material->title or '' }}}<span class="color pull-right">{{ FileHelper::formatBytes($marketing_material->media_size,0) }}</span></h6>
<!-- Shopping item hover block & link -->
<div class="item-hover bg-color hidden-xs">
Download
</div>
</div>
</div>
#endforeach
</div>
<hr>
#endforeach
Can someone help me how to resolve this ?
Bootstrap doesn't support that kind of scrolling. However, I have used this JavaScript library in the past and it does pretty much exactly what you want: Slick.js
It is very flexible and it will only show the scrolling options if it can't display all the contents on the page.
If you use it though, do not use the bootstrap col-md-2 classes, just set a manual width.

Resources