I am attempting to build a responsive material list view where each card includes an image, some textual details and some user actions.
The textual details can vary between items in the list, so the card heights can vary. As the design needs to be responsive, the width of the card can also vary.
What I need to do is ensure that the image is always a square. I've seen good answers here on how to achieve that in a vertical layout, but not in a horizontal layout.
Here is a mockup of what I am trying to achieve using Flex to show the box layout. I am not tied to Flex as part of the solution.
Sample code
.card {
display: flex;
flex-flow: row wrap;
width: 100%;
margin-bottom: 15px;
}
.card .title {
line-height: 3rem;
font-size: 1.5rem;
font-weight: 300;
}
.card .action {
background: grey;
order: 3;
flex-basis: 100%;
}
.card .content {
background: red;
order: 2;
flex-grow: 1;
}
.card .image {
background: gold;
order: 1;
flex-grow: 1;
}
<div class="row">
<div class="medium-6 columns end">
<div class="card">
<div class="content">
<span class="title">
Just a Title
</span>
</div>
<div class="action">
<p>this is an action</p>
</div>
<div class="image">
<p>Image goes here</p>
</div>
</div>
<div class="card">
<div class="content">
<span class="title">
Title with some text
</span>
<P>This is some content under the title</P>
</div>
<div class="action">
<p>this is an action</p>
</div>
<div class="image">
<p>Image goes here</p>
</div>
</div>
<div class="card">
<div class="content">
<span class="title">
Title with more text
</span>
<P>This is some content under the title</P>
<P>Second line of text</P>
</div>
<div class="action">
<p>this is an action</p>
</div>
<div class="image">
<p>Image goes here</p>
</div>
</div>
</div>
</div>
Try adding this script at the end of your work:
<script type="text/javascript" src="http://code.jquery.com/jquery-1.6.2.js"></script>
<script>
var cw = $('.image').width();
$('.image').css({
'height': cw + 'px'
});
</script>
EDIT
To act upon window resize, try this:
<script type="text/javascript" src="http://code.jquery.com/jquery-1.6.2.js"></script>
<script>
var cw = $('.image').width();
$('.image').css({
'height': cw + 'px'
});
window.onresize = function(event) {
var cw = $('.image').width();
$('.image').css({
'height': cw + 'px'
});
};
</script>
You can do it if your images will be square
.card {
display: flex;
flex-flow: row wrap;
width: 100%;
margin-bottom: 15px;
}
.card .title {
line-height: 3rem;
font-size: 1.5rem;
font-weight: 300;
}
.card .action {
background: grey;
order: 3;
flex-basis: 100%;
}
.card .content {
background: red;
order: 2;
flex-grow: 1;
}
.card .image {
background: gold;
order: 1;
flex: 1;
max-width: 30vw; /* scale img block with page */
}
.card .image img {
display: block;
width: 100%;
}
<div class="row">
<div class="medium-6 columns end">
<div class="card">
<div class="content">
<span class="title">
Just a Title
</span>
</div>
<div class="action">
<p>this is an action</p>
</div>
<div class="image">
<img src="https://placeholdit.imgix.net/~text?txtsize=33&txt=img%20goes%20here&w=300&h=300">
</div>
</div>
<div class="card">
<div class="content">
<span class="title">
Title with some text
</span>
<P>This is some content under the title</P>
</div>
<div class="action">
<p>this is an action</p>
</div>
<div class="image">
<img src="https://placeholdit.imgix.net/~text?txtsize=33&txt=img%20goes%20here&w=300&h=300">
</div>
</div>
<div class="card">
<div class="content">
<span class="title">
Title with more text
</span>
<P>This is some content under the title</P>
<P>Second line of text</P>
</div>
<div class="action">
<p>this is an action</p>
</div>
<div class="image">
<img src="https://placeholdit.imgix.net/~text?txtsize=33&txt=img%20goes%20here&w=300&h=300">
</div>
</div>
</div>
</div>
Related
How do I change the order of this code in mobile?
Currently on desktop <div class="grid4-12">(left) and <div class="grid8-12">(right) are stacked to each other.
How do I change the code in responsive such that <div class="grid8-12"> is on top and <div class="grid4-12"> is at the bottom?
Code below
<div class="card-content-lg" style=" background: #ffffff;">
<div class="grid4-12">
<div class="quote-wrapper test">
<div class="quote-col1 test">
<div class="quote-image"><img alt="Image1" src="/images" /></div>
</div>
<div class="quote-col2 test2">
<div class="quote-text">This is only test</div>
</div>
<div class="quote-col3">
<div><img alt="ABC" src="/images" /></div>
</div>
</div>
</div>
<div class="grid8-12">
<div class="card-content-md">
<h2 class="abc">This is h2 text</h2>
<p>This is a test.</p>
</div>
</div>
</div>
You can give the parent class (.card-content-lg) a display value of flex, with flex-direction set to column. Then, on the "second" / "right" element, give it a value of "order: -1;". Then, change the value of flex-direction to "row" on larger viewports, and change the order back to 1.
.card-content-lg {
display: flex;
flex-direction: column;
}
#media all and (min-width: 640px) {
.card-content-lg {
display: flex;
flex-direction: row;
}
}
.grid4-12, .grid8-12 {
background: gray;
min-height: 6rem;
margin: 1rem;
padding: 1rem;
color: white;
}
.grid8-12 {
order: -1;
}
#media all and (min-width: 640px) {
.grid8-12 {
order: 1;
}
}
<div class="card-content-lg" style=" background: #ffffff;">
<div class="grid4-12">
<div class="quote-wrapper test">
<div class="quote-col1 test">
<div class="quote-image"><img alt="Image1" src="/images" /></div>
</div>
<div class="quote-col2 test2">
<div class="quote-text">This is only test</div>
</div>
<div class="quote-col3">
<div><img alt="ABC" src="/images" /></div>
</div>
</div>
</div>
<div class="grid8-12">
<div class="card-content-md">
<h2 class="abc">This is h2 text</h2>
<p>This is a test.</p>
</div>
</div>
</div>
make card-content-lg a flexbox and use media queries to reverse direction using flex-direction: row-reverse
add css of your code so we can attach a working sample as well.
In this CodePen, I am trying to get the .icon div to appear the full height of the div it's in. Unfortunately, it looks like it's loading before the text is there so the div has a height of 0 when it loads. How would I get it to load once the text is there and grab that full height? Preferably with no JS if possible.
All help is appreciated!
HTML
.faqSection {
height: 600px;
width: 100vw;
}
.topFaqSection {
margin: 100px 0 40px 10vw;
}
.innerFaqSection {
height: 100%;
width: 100%;
display: flex;
justify-content: center;
}
.leftFaq {
width: 35%;
height: 100%;
/* background-color: violet; */
}
.rightFaq {
width: 35%;
height: 100%;
/* background-color: blanchedalmond; */
}
.singleFaqBlock {
margin: 20px 0 0 0;
}
.questionBlock {
background-color: red;
display: flex;
flex-direction: row;
align-content: flex-start;
}
.icon {
background-color: blue;
width: 50px;
height: 100%;
}
.questionText {
/* display: none; */
background-color: green;
width: 100%;
}
.answerBlock {}
.answerBlock p {
margin: 0 0 0 62px;
}
.hiddenText {
display: none;
}
.notHiddenText {
display: block;
}
<div class="faqSection">
<div class="topFaqSection">
<h1>Questions? Look Here</h1>
<div class="bar blue"></div>
</div>
<div class="innerFaqSection">
<div class="leftFaq">
<div class="singleFaqBlock">
<div class="questionBlock">
<div class="icon">
<div class="circle-plus closed">
<div class="circle">
<div class="horizontal"></div>
<div class="vertical"></div>
</div>
</div>
</div>
<div class="questionText">
<h3>
How do I earn a return?
</h3>
</div>
</div>
<div class="answerBlock">
<p class="hiddenText">
Yes! We would love to answer your question thank you for giving us the opoportunity!!
</p>
</div>
</div>
<div class="singleFaqBlock">
<div class="questionBlock">
<div class="icon">
<div class="circle-plus closed">
<div class="circle">
<div class="horizontal"></div>
<div class="vertical"></div>
</div>
</div>
</div>
<div class="questionText">
<h3>
What kind of returns can I expect?
</h3>
</div>
</div>
<div class="answerBlock">
<p class="hiddenText">
Yes! We would love to answer your question thank you for giving us the opoportunity!!
</p>
</div>
</div>
</div>
<div class="space"></div>
<div class="rightFaq">
<div class="singleFaqBlock">
<div class="questionBlock">
<div class="icon">
<div class="circle-plus closed">
<div class="circle">
<div class="horizontal"></div>
<div class="vertical"></div>
</div>
</div>
</div>
<div class="questionText">
<h3>
When is the platform releasing?
</h3>
</div>
</div>
<div class="answerBlock">
<p class="hiddenText">
Yes! We would love to answer your question thank you for giving us the opoportunity!!
</p>
</div>
</div>
<div class="singleFaqBlock">
<div class="questionBlock">
<div class="icon">
<div class="circle-plus closed">
<div class="circle">
<div class="horizontal"></div>
<div class="vertical"></div>
</div>
</div>
</div>
<div class="questionText">
<h3>
Why invest in real estate? </h3>
</div>
</div>
<div class="answerBlock">
<p class="hiddenText">
Yes! We would love to answer your question thank you for giving us the opoportunity!!
</p>
</div>
</div>
<div class="singleFaqBlock">
<div class="questionBlock">
<div class="icon">
<div class="circle-plus closed">
<div class="circle">
<div class="horizontal"></div>
<div class="vertical"></div>
</div>
</div>
</div>
<div class="questionText">
<h3>
I'm a - and interested in raising money through -, what should I do? </h3>
</div>
</div>
<div class="answerBlock">
<p class="hiddenText">
Yes! We would love to answer your question thank you for giving us the opoportunity!!
</p>
</div>
</div>
</div>
</div>
</div>
As I said in a a comment, removing the height: 100% rule should fix it for you. The "why" for it is a bit... unsavory.
Flex children default to "align-self: stretch", so they'll stretch naturally. But when you set a height, it will use that value. The problem is percentage height is calculated from the height actually specified for the parent and .icon's parent (.questionBlock) has no height specified: so .icon gets 100% of 0. If you were to set a height to .questionBlock, .icon would adapt.
From the specs:
The percentage is calculated with
respect to the height of the generated box's containing block. If the
height of the containing block is not specified explicitly (i.e., it
depends on content height), and this element is not absolutely
positioned, the value computes to 'auto'.
This is the comment that pointed me into the right direction. Maybe check it out?
I have a row with six columns of image and text here: https://i.imgur.com/UKGGCrX.png
I want to align the two-line text (e.g. Resources and Reserves) with "Exploration" and "Geological Data". https://i.imgur.com/Tplzivb.png
Adding a margin below the image doesn't do the trick, nor does adding a margin above the text... also tried setting a min-height for the icon, but that doesn't do it either.
How can I accomplish this?
Using flexbox you can easily align your text on "top".
This is default flexbox behaviour and does align your text on "baseline":
.container{
display: flex;
flex-flow: row nowarp;
}
.text{
max-width: 30px;
}
<html>
<div class="container">
<div class="imgt">
<img src="https://dummyimage.com/20x20">
<div>Some Text</div>
</div>
<div class="imgt">
<img src="https://dummyimage.com/20x20">
<div class="text">Some Long long Text</div>
</div>
</div>
</html>
I assume you have a margin-top: auto; and margin-bottom: auto;, or some flexbox properties like align-items: center; somewhere, that your text gets centered inside the div.
You can use flex styles to obtain your desired results. I created an example showing how the align-items: stretch; property will help with keeping icons/images/and content aligned with siblings.
Live example: https://codepen.io/SROwl/pen/xNrRmw
HTML:
<h3> align content top </h3>
<div class="bucket-row">
<div class="bucket">
<img src="https://dummyimage.com/85x85">
<span>Single Line</span>
</div>
<div class="bucket">
<img src="https://dummyimage.com/85x85">
<span>Double Line Title</span>
</div>
<div class="bucket">
<img src="https://dummyimage.com/85x85">
<span>Double Line Title</span>
</div>
<div class="bucket">
<img src="https://dummyimage.com/85x85">
<span>Single Line</span>
</div>
<div class="bucket">
<img src="https://dummyimage.com/85x85">
<span>Triplen Extra Line Title</span>
</div>
<div class="bucket">
<img src="https://dummyimage.com/85x85">
<span>Double Line Title</span>
</div>
</div>
<h3> align content bottom </h3>
<div class="bucket-row content-end">
<div class="bucket">
<img src="https://dummyimage.com/85x85">
<span>Single Line</span>
</div>
<div class="bucket">
<img src="https://dummyimage.com/85x85">
<span>Double Line Title</span>
</div>
<div class="bucket">
<img src="https://dummyimage.com/85x85">
<span>Double Line Title</span>
</div>
<div class="bucket">
<img src="https://dummyimage.com/85x85">
<span>Single Line</span>
</div>
<div class="bucket">
<img src="https://dummyimage.com/85x85">
<span>Triplen Extra Line Title</span>
</div>
<div class="bucket">
<img src="https://dummyimage.com/85x85">
<span>Double Line Title</span>
</div>
</div>
SCSS:
body {
font-family: sans-serif;
}
.bucket-row {
display: flex;
flex-direction: row;
align-items: stretch;
justify-content: space-between;
width: 600px;
margin-bottom: 40px;
.bucket {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
max-width: 85px;
background-color: #eee;
padding-bottom: 20px;
img {
margin-bottom: 15px;
}
}
&.content-end {
.bucket {
span {
margin-top: auto;
}
}
}
}
For example - I have an ordered list <ol> with 7 <li> items in it and each one of them contains some <div></div> containers and one of them is <div class="title"></div>. And when resizing screen in one of the <li> items title container breaks and makes 2 lines. Is it possible to expand all other <div class="title"></div> that in all li items that container still matches in height?
I mean using just css, without javascript
In pictures - Current result -
Expected result -
Thank you a lot for any advice! :)
able with grid.
.box {
width:360px;
display:grid;
grid-template-columns:100px 100px 100px;
grid-gap:20px;
grid-auto-rows:30px;
background:#f0f0f0;
padding:10px;
}
.price1, .price2, .price3 {
font-weight:bold;
}
<div class="box">
<div class="text1">asdasd asdasda sad as asd</div>
<div class="text2">asdasd asd</div>
<div class="text3"> asdasd asd </div>
<div class="price1">$58.00</div>
<div class="price2">$58.00</div>
<div class="price3">$58.00</div>
</div>
Please find below code:
var maxHeight = -1;
$('.product-item').each(function() {
if ($(this).find('.product-item-brand').height() > maxHeight) {
maxHeight = $(this).find('.product-item-brand').height();
}
});
$('.product-item-brand').height(maxHeight);
var maxHeight1 = -1;
$('.product-item').each(function() {
if ($(this).find('.product-item-link').height() > maxHeight) {
maxHeight = $(this).find('.product-item-link').height();
}
});
$('.product-item-link').height(maxHeight);
jQuery(window).resize(function() {
var maxHeight = -1;
$('.product-item').each(function() {
if ($(this).find('.product-item-brand').height() > maxHeight) {
maxHeight = $(this).find('.product-item-brand').height();
}
});
$('.product-item-brand').height(maxHeight);
var maxHeight1 = -1;
$('.product-item').each(function() {
if ($(this).find('.product-item-link').height() > maxHeight) {
maxHeight = $(this).find('.product-item-link').height();
}
});
$('.product-item-link').height(maxHeight);
});
.product-items {
list-style-type: none;
display: flex;
flex-wrap: wrap;
}
.product-item {
max-width: 200px;
max-height: 262px;
text-align: center;
}
.product-item-name {
border: 1px solid red;
a {
text-decoration: none;
}
}
.product-item-link {
-webkit-box-orient: vertical;
display: -webkit-box;
-webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
}
.product-item-brand {
line-height: 15px;
border: 1px solid black;
}
.product-price {
margin-top: 20px;
line-height: 19px;
border: 1px solid green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ol class="products list items product-items">
<li class="product-item">
<div class="product-item-info">
<div class="product details product-item-details">
<div class="product-item-brand">
this one have brand name
</div>
<div class="product name product-item-name">
<a class="product-item-link" href="#">long word goes here will break in 2 rows, qwerty 123456</a>
</div>
<div class="product-price-block">
<div class="product-price">
$15
</div>
</div>
</div>
</div>
</li>
<li class="product-item">
<div class="product-item-info">
<div class="product details product-item-details">
<div class="product-item-brand">
this one also
</div>
<div class="product name product-item-name">
<a class="product-item-link" href="#">long word goes here</a>
</div>
<div class="product-price-block">
<div class="product-price">
$15
</div>
</div>
</div>
</div>
</li>
<li class="product-item">
<div class="product-item-info">
<div class="product details product-item-details">
<div class="product-item-brand">
next doesnt have, need to set empty space
</div>
<div class="product name product-item-name">
<a class="product-item-link" href="#">long word goes here</a>
</div>
<div class="product-price-block">
<div class="product-price">
$15
</div>
</div>
</div>
</div>
</li>
<li class="product-item">
<div class="product-item-info">
<div class="product details product-item-details">
<div class="product-item-brand">
</div>
<div class="product name product-item-name">
<a class="product-item-link" href="#">long word goes here</a>
</div>
<div class="product-price-block">
<div class="product-price">
$15
</div>
</div>
</div>
</div>
</li>
</ol>
How do I align the div so that both label has the same width and right aligned and both content start at the same place. Some suggest float, but I dont perfer floating the content. Is there a flex way of doing this.
<!DOCTYPE HTMML>
<html>
<body>
<div>
<div style="display: flex; flex-direction:row;">
<div style="align: right; background: blue">
Long label:
</div>
<div style="text-align: left; background: green">
This is the content
</div>
</div>
<div style="display: flex; flex-direction:row;">
<div style="align: right; background: blue">
label:
</div>
<div style="text-align: left; background: green">
This is the content
</div>
</div>
</div>
</body>
</html>
With flexbox...NO...you can't unless you use fixed width values (whatever they are)...there is no width/height equalisation between non-siblings.
You would need to given one of the elements a fixed width value and then let the other take up the remaining space with flex:1.
.blue {
background: lightblue;
/* width: 150px; */
flex: 0 0 150px
}
.green {
background: #bada55;
flex: 1;
}
.parent {
display: flex;
}
<div class="parent">
<div class="blue">
Long label:
</div>
<div class="green">
This is the content
</div>
</div>
<div class="parent">
<div class="blue">
label:
</div>
<div class="green">
This is the content
</div>
</div>
Why not simply add a class to the content and label divs?
HTML
<div>
<div>
<div class="label-div">Long label</div>
<div class="content-div">Content</div>
</div>
<div>
<div class="label-div">Label</div>
<div class="content-div">Content</div>
</div>
</div>
CSS
.label-div {
width: 70px;
text-align: right;
}
.content-div {
text-align: left;
}
This way, you can be sure that all label divs are equal in length.