Bootstrap 4 want uneven column heights [duplicate] - javascript

Is there a way to create a masonry column layout utilizing the flexbox grid that Bootstrap 4 comes equipped with? It seems to me that all of the columns are equal height.

This is pretty much doable with standard Bootstrap 4 classes. There is even a whole section in the documentation about the Card columns feature.
From the docs:
Cards can be organized into Masonry-like columns with just CSS by wrapping them in .card-columns. Cards are built with CSS column properties instead of flexbox for easier alignment. Cards are ordered from top to bottom and left to right.
Heads up! Your mileage with card columns may vary. To prevent cards breaking across columns, we must set them to display: inline-block as column-break-inside: avoid isn’t a bulletproof solution yet.
So, all you have to do is to wrap your .cards into a .card-columns container like this:
<div class="container">
<div class="card-columns">
<div class="card">
<img class="card-img-top" src="http://via.placeholder.com/1600x900/483D8B/ffffff?text=Card+1" alt="Card image cap">
<div class="card-body">
<h5 class="card-title">Card title that wraps to a new line</h5>
<p class="card-text">This is a longer card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.</p>
</div>
</div>
<div class="card p-3">
<blockquote class="blockquote mb-0 card-body">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.</p>
<footer class="blockquote-footer">
<small class="text-muted">
Someone famous in <cite title="Source Title">Source Title</cite>
</small>
</footer>
</blockquote>
</div>
<div class="card">
<img class="card-img-top" src="http://via.placeholder.com/1600x450/9400D3/ffffff?text=Card+2" alt="Card image cap">
<div class="card-body">
<h5 class="card-title">Card title</h5>
<p class="card-text">This card has supporting text below as a natural lead-in to additional content.</p>
<p class="card-text"><small class="text-muted">Last updated 3 mins ago</small></p>
</div>
</div>
<div class="card bg-primary text-white text-center p-3">
<blockquote class="blockquote mb-0">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat.</p>
<footer class="blockquote-footer">
<small>
Someone famous in <cite title="Source Title">Source Title</cite>
</small>
</footer>
</blockquote>
</div>
<div class="card text-center">
<div class="card-body">
<h5 class="card-title">Card title</h5>
<p class="card-text">This card has supporting text below as a natural lead-in to additional content.</p>
<p class="card-text"><small class="text-muted">Last updated 3 mins ago</small></p>
</div>
</div>
<div class="card">
<img class="card-img" src="http://via.placeholder.com/1600x1600/FF1493/ffffff?text=Card+3" alt="Card image">
</div>
<div class="card p-3 text-right">
<blockquote class="blockquote mb-0">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.</p>
<footer class="blockquote-footer">
<small class="text-muted">
Someone famous in <cite title="Source Title">Source Title</cite>
</small>
</footer>
</blockquote>
</div>
<div class="card">
<div class="card-body">
<h5 class="card-title">Card title</h5>
<p class="card-text">This is a wider card with supporting text below as a natural lead-in to additional content. This card has even longer content than the first to show that equal height action.</p>
<p class="card-text"><small class="text-muted">Last updated 3 mins ago</small></p>
</div>
</div>
</div>
</div>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet"/>

There's many choices for Mosonry Grid Layouts..
Here's Check it out 10 Code Snippets for Creating Masonry Grid Layouts
I prefer to use CSS
.masonry { /* Masonry container */
-webkit-column-count: 4;
-moz-column-count:4;
column-count: 4;
-webkit-column-gap: 1em;
-moz-column-gap: 1em;
column-gap: 1em;
margin: 1.5em;
padding: 0;
}
body {
font-family: sans-serif;
margin: 0;
background: #f2f2f2;
}
h1 {
text-align: center;
margin-top: 50px;
}
p {
text-align: center;
margin-bottom:60px;
}
h4{
text-align:center;
line-height:80px;
font-weight:normal;
}
.masonry { /* Masonry container */
-webkit-column-count: 4;
-moz-column-count:4;
column-count: 4;
-webkit-column-gap: 1em;
-moz-column-gap: 1em;
column-gap: 1em;
margin: 1.5em;
padding: 0;
-moz-column-gap: 1.5em;
-webkit-column-gap: 1.5em;
column-gap: 1.5em;
font-size: .85em;
}
.item {
display: inline-block;
background: #fff;
padding: 1em;
margin: 0 0 1.5em;
width: 100%;
-webkit-transition:1s ease all;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-shadow: 2px 2px 4px 0 #ccc;
}
.item img{max-width:100%; height: auto;}
#media only screen and (max-width: 320px) {
.masonry {
-moz-column-count: 1;
-webkit-column-count: 1;
column-count: 1;
}
}
#media only screen and (min-width: 321px) and (max-width: 768px){
.masonry {
-moz-column-count: 2;
-webkit-column-count: 2;
column-count: 2;
}
}
#media only screen and (min-width: 769px) and (max-width: 1200px){
.masonry {
-moz-column-count: 3;
-webkit-column-count: 3;
column-count: 3;
}
}
#media only screen and (min-width: 1201px) {
.masonry {
-moz-column-count: 4;
-webkit-column-count: 4;
column-count: 4;
}
}
<h1>Responsive Masonry Grid</h1>
<p>A pure CSS-only responsive masonry.</p>
<div class="masonry">
<div class="item">
1
<img src="http://www.pixeden.com/media/k2/galleries/468/001-business-card-clip-brand-mock-up-vol-20-psd.jpg">
</div>
<div class="item">
2
<img src="http://www.graphicsfuel.com/wp-content/uploads/2015/11/branding-mockup-psd.jpg">
</div>
<div class="item">
3
<img src="http://www.pixeden.com/media/k2/galleries/511/001-business-card-mockup-vol-22-box-brand-psd.jpg">
</div>
<div class="item">
4
<img src="http://freede.ru/wp-content/uploads/2015/01/6546546542.jpg">
</div>
<div class="item">
5
<img src="https://blog.spoongraphics.co.uk/wp-content/uploads/2013/mockup/23.jpg">
</div>
<div class="item">
6
<img src="http://jquerypluginplus.com/wp-content/uploads/2015/09/Psd_Business_Card_MockUp.jpg">
</div>
<div class="item">
7
<img src="http://www.pixeden.com/media/k2/galleries/754/001-businesscard-mockup-presentation-psd-free-resource.jpg">
</div>
<div class="item">
8
<img src="http://designdecoding.com/wp-content/uploads/2014/09/001-a4-paper-brand-stationery-isometric-print-mock-up-psd-1.jpg">
</div>
<div class="item">
9
<img src="http://www.blugraphic.com/wp-content/uploads/2014/04/Folded-Page-Mockup1.jpg">
</div>
<div class="item">
10
<img src="http://cdn.designinstruct.com/files/542-free-branding-identity-mockups/29-branding-identity-mock-up-vol-8-full.jpg">
</div>
<div class="item">
11
<img src="http://www.thomsoon.com/img/portfolio/7clean/7-clean-business-card-mockup-psd-3.jpg">
</div>
<div class="item">
12
<img src="http://www.pixeden.com/media/k2/galleries/640/001-business-card-cardboard-mockup-presentation-wall-free-psd.jpg">
</div>
</div>
<h4>Photo from google.</h4>

By accident, I found how to kinda solve the ordering problem reported by #erik-thiart at Bootstrap 4 masonry layout utilizing flexbox grid
if you need to have the mason-like grid to follow the order left-to-right and top-to-bottom add a ROW to the class:
<div class="row card-columns">
the rows get fixed by the bigger card size, but it maintains the order.

Related

My bootstrap carousel background image doesn't adjust with the browser window size

Okay so I'm new to programming and I've been embarking on a project where I'm developing the front end for a personal website. I decided to use a bootstrap carousel background image slider in my index.html but the size of the page tends to shrink and the carousel text also shrinks and overlaps when I adjust my browser screen.
so this is a link to what I'm trying to say
my code is like this
.container {
margin-top: 20px;
}
.navbar{
background-color : #3e403e;
}
.text h1{
font-size: 110px
}
.text p{
font-size: 40px
}
hr{
background-color: white
}
.text a{
padding: 15px 80px 15px 80px;
}
.header-text {
position: absolute;
top: 20%;
left: 1.8%;
right: auto;
width: 96.66666666666666%;
}
<div id="indexCarousel" class="carousel slide" data-ride="carousel">
<div class="carousel-inner">
<div class="carousel-item active">
<img class="d-block w-100" src="images/background.png" alt="Slide One">
</div>
<div class="carousel-item">
<img class="d-block w-100" src="images/background 2.png" alt="Slide Two">
</div>
<div class="carousel-item">
<img class="d-block w-100" src="images/background 3.png" alt="Slide Three">
</div>
<div class="header-text hidden-xs">
<div class="col-md-12 text center">
<div class="container">
<div class="text">
<h1 class="display-4" style="color:white"><strong>Beats, Sounds Vibes!!!</strong></h1>
<p class="lead" style=" color:white">What are you waiting for?</p>
<hr class="my-4">
<p style="color: white">XQ's music is made from the purest selection of industry-level sounds
and
samples. Vibe with him, and you"ll see what we're talking about.</p>
<a class="btn btn-primary btn-lg" href="beats.html" role="button">Dive in</a>
</div>
</div>
</div>
</div>
</div>
</div>
I'll appreciate help.
use #media screen and (max-width: 600px) {} in css for small screen
#media screen and (max-width: 600px) {
.text h1{
font-size: 40px
}
}

Adding a Product List on Image

I am using the minimal template in Shopify and would like to recreate this image attached. I have tried researching for similar examples but can't seem to find anything. How do I go about creating this image? How do I get an image behind a menu?
Any links or documents to achieving image would really help.
Try to break down the design to work out it's constituent parts. You want a background image and an overlay with product cards. You want to position the overlay on top of the picture you do this by applying position:relative to the parent and position:absolute to the child so it will be positioned within it's parent. Then apply transform: translate() to translate the overlay dependant on it's size to achieve the offset on the right hand side.
Here's a pen : https://codepen.io/NeilWkz/pen/qgRMyW
<div class="img-hero-with-menu-overlay">
<div class="left-img">
</div>
<div class="overlay">
<div class="product-card">
<img src="https://lorempixel.com/300/150/" alt="">
<div class="info">
<h3>Product 1</h3>
<p>lorem</p>
</div>
</div>
<div class="product-card">
<img src="https://lorempixel.com/300/150/" alt="">
<div class="info">
<h3>Product 2</h3>
<p>lorem</p>
</div>
</div>
<div class="product-card">
<img src="https://lorempixel.com/300/150/" alt="">
<div class="info">
<h3>Product 3</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. </p>
</div>
</div>
</div>
</div>
The CSS
img-hero-with-menu-overlay {
position: relative;
background-color: #bcbdc0;
width: 100%;
display: block;
}
.left-img {
height: 100vh;
display: block;
width: 75%;
background: url("https://www.llialighting.com/Content/files/ProductImages/v_06f3_angled448253599.png")
no-repeat center center;
background-size: cover;
}
.overlay {
position: absolute;
right: 0;
top: 50%;
transform: translate(-12.5%, -50%);
width: 40%;
}
.product-card {
display: flex;
margin-bottom: 1.5rem;
}
.info {
padding: 1.5rem;
}

How to set same dynamic width of component child for all instances? Web Components

Assume I have a small component in a web application that represents an expander control, i.e. a header text, an icon to expand / collapse and some content.
A very simple React implementation (pseudo code) could look like this:
const Expander = ({children, title, onExpandToggle, isExpanded}) => (
<div>
<div><span>{title}</span><img src={...} onClick={onExpandToggle} /></div>
{isExpanded && children}
</div>
);
This implementation shows the icon after the title, so the position of the icon is determined by the length of the title.
It could look something like this:
Now assume that there are multiple like this below each other. It becomes messy:
To make this cleaner, all icons should have the same padding from left. The padding should not be fixed but dynamic, so that the longest title determines the position of all icons:
Assuming that I want to keep the expander in its own component, is there a CSS way to achieve my goal?
So far, I haven't tried anything as I don't have a starting point. In WPF I would have used something like SharedSizeGroup, but this doesn't exist for CSS.
Assuming you'll have a container to your component, you can set display: flex to the inner container and align-self: flex-end to your image.
Then wrap your component/s with a div that has display: inline-block which takes the width of the biggest element inside.
Here's an example:
.container{
display: inline-block;
padding: 3px;
}
.item{
display: flex;
flex-direction: row;
justify-content: space-between;
}
.item .plus{
width: 15px;
height: 15px;
background-image: url("https://cdn1.iconfinder.com/data/icons/mix-color-3/502/Untitled-43-512.png");
background-size: cover;
background-repeat: no-repeat;
align-self: flex-end;
margin-left: 10px;
}
<div class="container">
<div class="item">
<div>Synonyms</div>
<div class="plus"></div>
</div>
<div class="item">
<div>Concept</div>
<div class="plus"></div>
</div>
<div class="item">
<div>Term</div>
<div class="plus"></div>
</div>
</div>
Affecting all the instances without a shared container or fixed width and with CSS alone, is not possible, since there is no way to access a parent element with CSS. Therefore, If you'll have an inner instance (the biggest one) it won't be able to apply it's width to its own parent or any ancestor and it's other children.
If you're after a solution that will set all the instances in the page with the same size without them sharing a container you can achieve it with JS.
Calculate the width of each instance, save the biggest, then set this width for the rest of the instances. In this example I'm also highlighting the biggest item. The items are all around the page and can be inside various divs and displays or without any container.
var biggestWidth = 0;
var biggestItem;
function setWidth() {
$(".item").each(function() {
var currentWidth = $(this).width();
if (currentWidth > biggestWidth) {
biggestWidth = Math.ceil(currentWidth);
biggestItem = $(this);
}
});
$(".item").width(biggestWidth);
biggestItem.addClass("biggest");
}
$(setWidth());
section {
width: 40%;
float: left;
border: 1px solid black;
border-radius: 3px;
margin: 10px;
padding: 10px;
}
.s1 {
background-color: #e5e5e5;
display: table;
}
.item {
display: inline-block;
clear: both;
float: left;
}
.txt {
float: left;
display: inline-block;
}
.plus {
width: 15px;
height: 15px;
background-image: url("https://cdn1.iconfinder.com/data/icons/mix-color-3/502/Untitled-43-512.png");
background-size: cover;
margin-left: 10px;
float: right;
}
.shift{
margin-left: 30%;
}
.clear{
clear: both;
}
.biggest{
background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section class="s1">
<div class="item">
<div class="txt">Synonyms</div>
<div class="plus"></div>
</div>
<div class="item">
<div class="txt">Concept</div>
<div class="plus"></div>
</div>
<div class="item">
<div class="txt">Term</div>
<div class="plus"></div>
</div>
</section>
<section>
<div class="item">
<div class="txt">Synonyms</div>
<div class="plus"></div>
</div>
<div class="item">
<div class="txt">Concept</div>
<div class="plus"></div>
</div>
<div class="item">
<div class="txt">Term</div>
<div class="plus"></div>
</div>
</section>
<section>
<div class="item">
<div class="txt">Synonyms - Long</div>
<div class="plus"></div>
</div>
<div class="item">
<div class="txt">Concept</div>
<div class="plus"></div>
</div>
<div class="item">
<div class="txt">Term</div>
<div class="plus"></div>
</div>
</section>
<div class="item">
<div class="txt">Synonyms</div>
<div class="plus"></div>
</div>
<div class="item">
<div class="txt">Concept</div>
<div class="plus"></div>
</div>
<div class="item">
<div class="txt">Term</div>
<div class="plus"></div>
</div>
<div class="clear"></div>
<div class="shift">
<div class="item">
<div class="txt">Synonyms</div>
<div class="plus"></div>
</div>
<div class="item">
<div class="txt">Concept</div>
<div class="plus"></div>
</div>
<div class="item">
<div class="txt">The bigget item is here</div>
<div class="plus"></div>
</div>
</div>
You can also try using the css display property "table-row" and "table-cell".
style:
.trow {
display: table-row;
}
.tcell
{
display: table-cell;
padding: 2px;
}
You can design your component like following.
const Expander = ({children, title, onExpandToggle, isExpanded}) => (
<div className="trow">
<div className="tcell">{title}</div>
<div className="tcell"><img src={...} onClick={onExpandToggle} /></div>
{isExpanded && children}
</div>
);
Example
.trow {
display: table-row;
}
.tcell
{
display: table-cell;
padding: 2px;
}
<div>
<div class="trow">
<div class="tcell">Synonyms</div>
<div class="tcell">X</div>
</div>
<div class="trow">
<div class="tcell">Concept</div>
<div class="tcell">X</div>
</div>
<div class="trow">
<div class="tcell">Term</div>
<div class="tcell">X</div>
</div>
</div>
I think that strictly speaking, with all the restrictions you've laid out, the answer is "no, it's not possible".
But since I believe that you need, at any rate, to group those expanders somehow (alternative being that every expander on the page would be horizontally aligned, to which no complete CSS solution exists either), you can simply count on the CSS box model.
<div style="background-color: #efffef; display: inline-block;">
<div style="position: relative; padding-right: 36px;">
<span>Title 1</span>
<span style="position: absolute; right: 0; top: 0;">[x]</span>
</div>
<div style="position: relative; padding-right: 36px;">
<span>Long title 2</span>
<span style="position: absolute; right: 0; top: 0;">[x]</span>
</div>
<div style="position: relative; padding-right: 36px;">
<span>Title 3, at your service</span>
<span style="position: absolute; right: 0; top: 0;">[x]</span>
</div>
</div>
I personally would do it with classic <table>. Its easy, semantically correct, and it will be done in 3 minutes. But we could do it also with display:inline-block and float:right, or with <table>-imitation using display:table, display:table-row and display:table-cell. In my opinion display: flex is relative new and not overall cross-browser compatible (for example IE10, IE11 and others). Because of all it I would like to provide you 3 solutions.
Solution with display:inline-block and float:right
With display:inline-block the size is always aligned on the content.
.container,
.item div,
.item b{display:inline-block}
.item b
{
float:right;
width:16px;
height:16px;
margin-left:5px;
cursor:pointer;
background:url("https://i.stack.imgur.com/bKWrw.png")
}
<div class="container">
<div class="item">
<div>Synonyms</div>
<b></b>
</div>
<div class="item">
<div>Concept</div>
<b></b>
</div>
<div class="item">
<div>Term</div>
<b></b>
</div>
</div>
<br style="clear:both">
Solution with <table>-imitation
.container{display:table}
.item{display:table-row}
.item div{display:table-cell; vertical-align:top}
.item b
{
display:inline-block;
width:16px;
height:16px;
cursor:pointer;
margin-left:5px;
background:url("https://i.stack.imgur.com/bKWrw.png")
}
<div class="container">
<div class="item">
<div>Synonyms</div>
<div><b></b></div>
</div>
<div class="item">
<div>Concept</div>
<div><b></b></div>
</div>
<div class="item">
<div>Term</div>
<div><b></b></div>
</div>
</div>
Solution with classic <table> (my favorite)
.menu td{vertical-align:top}
.menu td b
{
display:inline-block;
width:16px;
height:16px;
cursor:pointer;
margin-left:5px;
background:url("https://i.stack.imgur.com/bKWrw.png")
}
<table class="menu" cellpadding="0" cellspacing="0">
<tr>
<td>Synonyms</td>
<td><b></b></td>
</tr>
<tr>
<td>Concept</td>
<td><b></b></td>
</tr>
<tr>
<td>Term</td>
<td><b></b></td>
</tr>
</table>
The simplest example I can think of, based on your code snippet, would be something like:
const containerStyle = {
width: `[whatever width you need for the container]`,
display: `flex`,
flexDirection: `column`
}
const itemStyle = {
width: `100%`,
display: `flex`,
flexDirection: `row`,
justifyContent: `space-between`
}
const Expander = ({children, title, onExpandToggle, isExpanded}) => (
<div style={containerStyle}>
<div style={itemStyle}>
<span>{title}</span>
<img src={...} onClick={onExpandToggle} />
</div>
{isExpanded && children}
</div>
);
const Expander = (children, title, onExpandToggle, isExpanded) => (
<div>
{title}
<img src={...} style={{marginLeft : '5px',float : 'right'}} onClick={onExpandToggle}/>
</div>
<div style={{width : '0px',overflowX : 'visible'}}>
{isExpanded && <div>
{children}
</div>}
</div>
);
And put it in:
<div style={{display : 'inline-block'}}>
<Expander />
<Expander />
</div>
In CSS it is not possible for different elements of a page to "know" each other. The closest thing you can get is to use display flex and/or grid. This way the direct parent can control the way its children will display, kind of similar to React.
The main difference between flex and grid is that flex is 1 axis and grid 2 axis.
Working example using grid and flex:
<div class="container">
<div class="summary"><span class="text">Synonyms</span> <span class="icon">+</span></div>
<div class="details">
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Eveniet officiis sequi perspiciatis sapiente iure minus laudantium! Quidem iure consectetur quod odit iusto, labore sunt quae, enim nesciunt officiis, quia ad.</p>
</div>
<div class="summary"><span class="text">Concept</span> <span class="icon">+</span></div>
<div class="details">
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Eveniet officiis sequi perspiciatis sapiente iure minus laudantium! Quidem iure consectetur quod odit iusto, labore sunt quae, enim nesciunt officiis, quia ad.</p>
</div>
<div class="summary"><span class="text">Terms</span> <span class="icon">+</span></div>
<div class="details">
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Eveniet officiis sequi perspiciatis sapiente iure minus laudantium! Quidem iure consectetur quod odit iusto, labore sunt quae, enim nesciunt officiis, quia ad.</p>
</div>
</div>
<style>
.container {
display: grid;
/* summary's width needs to be relative to the longest text
and details needs to span the whole grid */
grid-template-columns: auto auto;
}
.summary {
grid-column: 1 / 2; /* start at the beginning of 1st column and end at the beginning of the 2nd column */
display: flex; /* create horizontal layout */
justify-content: space-between; /* place the available space between the children */
}
.details {
grid-column: 1 / 3; /* start at the beginning of 1st column and end at the end of the 2nd column */
}
</style>
As you can see, it is very readable and requires very little markup.
With flex and grid you need to think on 2 levels parent > child. This means you need to change your React component accordingly:
const Expander = ({children, title, onExpandToggle, isExpanded}) => (
<>
<div class="summary" onClick={onExpandToggle}><span class="title">{title}</span> <span class="icon">+</span></div>
{isExpanded && (
<div class="details">
{children}
</div>
)}
</>
);
Here I removed the wrapper div in order to use a Fragment to ensure .summary and .details are direct children of a .container. Note that I also moved the onClick on the whole title for UX reasons.
CSS Grid is very useful and flexible, it is worth learning it. The browser support is recent but quite good, just make sure you use autoprefixer.
You can also use tricks using display: inline-block; whose size is based on its children but will involve workarounds when one of the children needs to overflow (like in your case). So I don't recommend it. I would also advise against using Javascript.
Don't hesitate to tell me what you think about this answer.
It is possible.
1. Flex-box + Absolution:
if you don't mind to use absolute positioned container, you can do it in this way
.container {
display: inline-flex;
flex-direction: column;
align-items: stretch;
width: auto;
}
.item {
margin: 5px 0;
padding: 5px;
border: 1px solid black;
}
.header {
display: flex;
align-items: center;
justify-content: space-between;
}
.header img {
width: 8px;
height: 8px;
margin-left: 20px;
cursor: pointer;
}
<div class="container">
<div class="item">
<div class="header">
<span>Synonyms</span>
<img src="https://image.flaticon.com/icons/png/512/61/61155.png" />
</div>
</div>
<div class="item">
<div class="header">
<span>Concept</span>
<img src="https://image.flaticon.com/icons/png/512/61/61155.png" />
</div>
</div>
<div class="item">
<div class="header">
<span>Term</span>
<img src="https://image.flaticon.com/icons/png/512/61/61155.png" />
</div>
</div>
</div>
The main problem here is that you don't know the height of the container so it might influence other content.
2. Inline Flex-box:
if the container position is critical for you, you can use inline-flex
.wrapper {
margin: 20px 10px;
}
.container {
display: inline-flex;
flex-direction: column;
align-items: stretch;
width: auto;
}
.item {
margin: 5px 0;
padding: 5px;
border: 1px solid black;
}
.header {
display: flex;
align-items: center;
justify-content: space-between;
}
.header img {
width: 8px;
height: 8px;
margin-left: 20px;
cursor: pointer;
}
Some content above the container...
<div class="wrapper">
<div class="container">
<div class="item">
<div class="header">
<span>Synonyms</span>
<img src="https://image.flaticon.com/icons/png/512/61/61155.png" />
</div>
</div>
<div class="item">
<div class="header">
<span>Concept</span>
<img src="https://image.flaticon.com/icons/png/512/61/61155.png" />
</div>
</div>
<div class="item">
<div class="header">
<span>Term</span>
<img src="https://image.flaticon.com/icons/png/512/61/61155.png" />
</div>
</div>
</div>
</div>
Some content below the container...

Jquery — Set child to fill remaining width of parent

I am building a responsive layout. I would like to know if anyone knows a way through JS/jQuery which I can set children to fill the remaining space of a parent only if there is space to fill (to the right).
Layout when above 900px
Layout when below 900px
HTML for reference
.row {
width: 100%;
}
.colm-span-2 {
position: relative;
float: left;
margin: 15px auto;
padding: 0px 15px 0px 15px;
background-color: #FFFFFF;
background-clip: content-box;
}
.colm-span-2 {
width: 33.3333333333%;
}
#media screen and (max-width: 900px) {
.colm-span-2 {
width: 50%;
}
}
<div class="row">
<div class="colm-span-2">
<div class="bg-white">
<div class="cont-span-1">
<h2>Test</h2>
<p>Lorem ipsum</p>
</div>
</div>
</div>
<div class="colm-span-2">
<div class="bg-cta-green">
<div class="cont-span-1">
<h2>Test</h2>
<p>Lorem ipsum</p>
</div>
</div>
</div>
<div class="colm-span-2">
<div class="bg-dark-purple">
<div class="cont-span-1">
<h2>Test</h2>
<p>Lorem ipsum</p>
</div>
</div>
</div>
</div>
I would suggest adding:
.colm-span-2:last-child {
width: 100%;
}
to your media query. This will change the final .colm-span-2 to have a 100% width.
With flexbox and :last-child (assuming you have rows) this is possible
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
::before,
::after {
box-sizing: inherit;
}
.bg-white {
background: whitesmoke;
}
.bg-cta-green {
background: green;
}
.bg-dark-purple {
background: rebeccapurple;
}
.row {
display: flex;
}
.colm-span-2 {
flex: 0 0 33%;
margin: .25em;
border: 1px solid grey;
}
.colm-span-2:last-child {
flex: 1;
}
<div class="row">
<div class="colm-span-2">
<div class="bg-white">
<div class="cont-span-1">
<h2>Test</h2>
<p>Lorem ipsum</p>
</div>
</div>
</div>
</div>
<div class="row">
<div class="colm-span-2">
<div class="bg-white">
<div class="cont-span-1">
<h2>Test</h2>
<p>Lorem ipsum</p>
</div>
</div>
</div>
<div class="colm-span-2">
<div class="bg-cta-green">
<div class="cont-span-1">
<h2>Test</h2>
<p>Lorem ipsum</p>
</div>
</div>
</div>
<div class="colm-span-2">
<div class="bg-dark-purple">
<div class="cont-span-1">
<h2>Test</h2>
<p>Lorem ipsum</p>
</div>
</div>
</div>
</div>
<div class="row">
<div class="colm-span-2">
<div class="bg-white">
<div class="cont-span-1">
<h2>Test</h2>
<p>Lorem ipsum</p>
</div>
</div>
</div>
<div class="colm-span-2">
<div class="bg-cta-green">
<div class="cont-span-1">
<h2>Test</h2>
<p>Lorem ipsum</p>
</div>
</div>
</div>
</div>

Uneven Responsive Image/Text Grid with Overlay

I've been trying to create the below layout to no avail. Would someone be kind enough to help me out in either creating a minimal working example or linking to somewhere that would be able to help me out with this?
What I need is a grid where the row heights are the same. With each row containing 2 images and 1 text column (the text column being placed in different locations in each row). The text column needs to be the same height as the images and I'd like the text to be vertically centered but the width of it needs to smaller (half the size). With the images, I'd like to have a white overlay on hover or touch(mobile) with a header and a couple lines for links and one link that will have a video popup (a la fancybox).
I'd like for this to be responsive and adapt to screen sizes. On mobile I'm fine with each box being 100% width but it's the tablet sizes I think I'm having issues with laying this thing out properly. The hover state would obviously need to become a touch state on these platforms.
I'd supply my code if need be but I think I'd like to just start from scratch since I feel like I've just created a huge mess.
I feel like this is something that should be so simple yet I'm having way too many problems with this and I can't seem to find any websites that showcase examples of what I'm trying to create....similar ideas have been found but not exactly what I'm looking for.
Details:
1140px as the max width of the container
444px as the max width of the images
222px as the max width of the text boxes
5px margin/padding
Any help in the right direction would be grateful.
http://jsfiddle.net/sa7v57bf/
<div class="container">
<ul>
<li class="text">
<div>
Some Text.
</div>
</li>
<li class="media">
<img src="http://placehold.it/444x342" alt="Image">
<div class="info">
<h2>HEADER</h2>
<div class="program-info">
<p>Program Page</p>
<p>Video</p>
</div>
</div>
</li>
<li class="media">
<img src="http://placehold.it/444x342" alt="Image">
<div class="info">
<h2>HEADER</h2>
<div class="program-info">
<p>Program Page</p>
<p>Video</p>
</div>
</div>
</li>
</ul>
<ul>
<li class="media">
<img src="http://placehold.it/444x342" alt="Image">
<div class="info">
<h2>HEADER</h2>
<div class="program-info">
<p>Program Page</p>
<p>Video</p>
</div>
</div>
</li>
<li class="text">
<div>
Some Text.
</div>
</li>
<li class="media">
<img src="http://placehold.it/444x342" alt="Image">
<div class="info">
<h2>HEADER</h2>
<div class="program-info">
<p>Program Page</p>
<p>Video</p>
</div>
</div>
</li>
</ul>
</div>
CSS:
*{box-sizing:border-box}.container{max-width:1140px;margin:0 auto;padding:0 10px}ul,ul li{padding:0}ul{list-style:none;margin:1% 0;font-size:0}ul li{display:inline-block;width:100%;margin:0 0 1%;height:100%;position:relative}ul li img{width:100%;display:block}ul li.text{background-color:#000;color:#FFF;padding:20px 10px;font-size:1.5rem;width:100%;vertical-align:top;text-align:center}#media (min-width:550px){ul li{width:50%}ul li.text div{margin:2%}}#media (min-width:1000px){ul li{width:39.5%;margin:0 .5%}ul li:first-child{margin-left:0}ul li:last-child{margin-right:0}ul li.text{width:19%;min-height:305px}}#media (min-width:1140px){ul li.text{min-height:341px}ul li.text div{margin:40% 0}}.info{background:rgba(255,255,255,.83);color:#000;font-size:2.4rem;left:10px;opacity:0;overflow:hidden;padding:3rem;position:absolute;top:10px;right:10px;bottom:10px;-webkit-transition:.6s;transition:.6s}.info:hover{opacity:1}
A combination of things here.
Flexbox for the equal heights, max-width where required, paddings/margin for spacing....oh, and positioning for the overlays.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.wrapper {
max-width: 1140px;
margin: auto;
margin-top: 5px;
border: 1px solid grey;
display: flex;
padding: 5px;
}
.wrapper > *:nth-child(2) {
margin: 0 5px;
}
.text,
header,
imgwrap {
flex: 1;
}
.text {
width: 20%;
padding: 1em;
max-width: 222px;
background: orange;
display: flex;
justify-content: center;
align-items: center;
}
header {
background: #bada55;
position: relative;
}
.imgwrap .overlay,
header .overlay {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
background: rgba(155, 0, 65, .25);
padding: 1em;
font-weight: bold;
color: #fff;
opacity: 0;
visibility: hidden;
transition: opacity .25s ease, visibility 0.25s ease;
}
.imgwrap:hover .overlay,
header:hover .overlay {
opacity: 1;
visibility: visible;
}
.imgwrap {
width: 40%;
position: relative;
}
.imgwrap img {
width: 100%;
display: block;
max-width: 444px;
}
<div class="wrapper">
<div class="text">Lorem ipsum dolor.</div>
<header>
<div class="overlay">Overlay Text</div>
</header>
<div class="imgwrap">
<img src="http://lorempixel.com/output/food-q-c-444-250-3.jpg" alt="" />
<div class="overlay">Image text</div>
</div>
</div>
<div class="wrapper">
<div class="imgwrap">
<img src="http://lorempixel.com/output/food-q-c-444-250-3.jpg" alt="" />
<div class="overlay">Image text</div>
</div>
<div class="text">Lorem ipsum dolor sit amet, consectetur adipisicing elit.</div>
<div class="imgwrap">
<img src="http://lorempixel.com/output/food-q-c-444-250-3.jpg" alt="" />
<div class="overlay">Image text</div>
</div>
</div>
Media queries can manage the rest.
Codepen Demo.

Categories

Resources