Scale images inside divs with text - css

For a personal project with Angular, Angular Material and Flex-Layout I am trying to achieve a similar layout used by Bring! App:
Having images of different size (not all squared) I would like to center them proportionally and allow some text under them.
I have the following template and scss styles:
<div fxLayout="row" fxLayoutGap="5px" class="cards-container">
<div class="item-card">
<div class="image">
<img src="../../../../assets/icons/apple.png" alt="Mela" />
</div>
<span class="item-name">Mela</span>
<span class="description">12</span>
</div>
<div class="item-card">
<div class="image">
<img src="../../../../assets/icons/milk.png" alt="Latte" />
</div>
<span class="item-name">Latte</span>
<span class="description">1 description comes here, must be hidden if long text</span>
</div>
</div>
//---------------------------------------------------
.cards-container {
flex-wrap: wrap;
.item-card {
display: flex;
flex-direction: column;
justify-items: end;
color: white;
width: 7em;
height: 7em;
text-align: center;
background-color: darkslategray;
margin: 5px 0;
img {
width: 40%; // TODO: how to scale?
height: 40%;
}
.text-container {
display: flex;
flex-direction: column;
.item-name {
display: inline-block;
font-size: 1.1em;
}
.description {
width: 99%;
font-size: 0.8em;
text-align: center;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
display: inline-block;
}
}
}
}
However the images do not scale down to keep the proportions with the others images, especially if narrow and long.

It all seems to look fine but it looks like your HTML code is missing the .text-container div and class.
<div class="item-card">
<div class="image">
<img src="../../../../assets/icons/apple.png" alt="Mela" />
</div>
<span class="item-name">Mela</span>
<span class="description">12</span>
</div>
should be
<div class="item-card">
<div class="image">
<img src="../../../../assets/icons/apple.png" alt="Mela" />
</div>
<div class="text-container">
<span class="item-name">Mela</span>
<span class="description">12</span>
</div>
</div>
Now for the text-overflow: ellipsis; this doesn't work on multi-lines unless you implement some JavaScript or something.
If there is any change to your code, I'd make the images a background-image instead. There could be other ways without this, but it's what I use to make sure the container is responsive with the image always responsive and centred.
For Example: https://codepen.io/StudioKonKon/pen/wRjOzr (Includes SCSS)
.image {
background-position: center center;
background-size: contain;
background-repeat: no-repeat;
font-size: 0;
}
.image-mela {
background-image: url("https://via.placeholder.com/150x175");
}
.image-latte {
background-image: url("https://via.placeholder.com/200x50");
}
.image-long {
background-image: url("https://via.placeholder.com/50x100");
}
.cards-container {
width: 100%;
margin: auto;
display: flex;
flex-wrap: wrap;
}
.cards-container .item-card {
display: flex;
flex-direction: column;
justify-items: end;
color: white;
width: 7em;
height: 7em;
text-align: center;
background-color: darkslategray;
margin: 5px;
padding: 0.5em;
box-sizing: border-box;
overflow: hidden;
}
.cards-container .item-card .image {
display: block;
margin: auto;
width: 40%;
height: 40%;
}
.cards-container .item-card .text-container {
display: flex;
flex-direction: column;
}
.cards-container .item-card .text-container .item-name {
display: inline-block;
font-size: 1.1em;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.cards-container .item-card .text-container .description {
font-size: 0.8em;
text-align: center;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
display: inline-block;
}
<div fxLayout="row" fxLayoutGap="5px" class="cards-container">
<div class="item-card">
<div class="image image-mela">Mela</div>
<div class="text-container">
<span class="item-name">Mela</span>
<span class="description">12</span>
</div>
</div>
<div class="item-card">
<div class="image image-latte">Latte</div>
<div class="text-container">
<span class="item-name">Latte</span>
<span class="description">1 description comes here, must be hidden if long text</span>
</div>
</div>
<div class="item-card">
<div class="image image-long">Long Image</div>
<div class="text-container">
<span class="item-name">Long Image Text</span>
<span class="description">must be hidden if long text</span>
</div>
</div>
</div>

Have you tried:
img {
width: 40%;
height: auto;
}
It should leave the image proportions consistent.

It is simple. I think it will solve the problem. :)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>item</title>
<style type="text/css" media="screen">
.item-single{
width: 100px;
background-color: #e7e7e7;
height: 100px;
text-align: center;
}
.item-single span{
display: block;
border: 1px solid #000; /* just to show the alignment */
}
.item-single img{
width: 50%; /* you can scale it down using width */
border:1px solid #000; /* just to show the alignment */
display: block;
margin: auto;
}
</style>
</head>
<body>
<div class="item-single">
<img src="http://sugamparajuli.com.np/wp-content/uploads/2019/01/banana.png">
<span class="item-name">Mela</span>
<span class="description">12</span>
</div>
</body>
</html>
This is the result.
item-image

Related

How to make adaptive centered div?

What I have now:
display: flex;
align-items: center;
flex-direction: column;
How it looks with error:
What's the target:
I can do it with
margin-left: *X*px, but it is not the way I want to solve it.
May I do it with some flex properties ?
It is important to do it without bootstrap and grid.
This could be a possible solution: Center the box with flexbox and display the errors with position: absolute;. You need to take care of responsive optimization if you want to use it on a wider range of devices.
* {
box-sizing: border-box;
}
.container {
display: flex;
align-items: center;
justify-content: center;
}
.box {
border: 1px solid black;
padding: 10px;
width: 400px;
}
.field {
position: relative;
}
.input {
margin-bottom: 10px;
width: 100%;
}
.error {
position: absolute;
left: 105%;
top: 0;
width: 200px;
}
<div class="container">
<div class="box">
<div class="field">
<input class="input" type="text">
<div class="error">error 1</div>
</div>
<div class="field">
<input class="input" type="text">
<div class="error">error 2</div>
</div>
<button>Send</button>
</div>
</div>

justify-content issues, align is working but justify not?

I am trying to center items vertically with justify-content while using the flex-column property applied. align-items is working as it should but the content is not responding to the Y axis. I have align-items commented out, I dont want to center X axis, just the Y axis.
.img1-container {
display: flex;
justify-content: center;
/* align-items: center; */
height: 100%;
}
.web-dev {
display: flex;
font-size: 60px;
}
.john-sass {
display: flex;
font-size: 48px;
margin-left: 38.5%;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet"/>
<div class="img1">
<div class="container img1-container d-flex flex-column justify-content-center">
<h1 class="into-text web-dev"> Front-End Web Developer</h1>
<h4 class="into-text john-sass">John Sasser</h4>
</div>
</div>
You need to do some div management to get this right , like this,
.img1 {
display: table;
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
}
.container {
display: table-cell;
vertical-align: middle;
}
.content{
margin-left: auto;
margin-right: auto;
width: 400px;
}
<div class="img1">
<div class="container img1-container d-flex flex-column justify-content-center">
<div class="content">
<h1 class="into-text web-dev"> Front-End Web Developer</h1>
<h4 class="into-text john-sass">John Sasser</h4>
</div>
</div>
</div>
just add justify-content: space-between; to your .img1-container class instead of justify-content: center;
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.img1-container {
display: flex;
justify-content: space-between;
align-items: center;
height: 100%;
width: 100%;
background-color: gray;
padding: 30px 0px;
}
.web-dev {
font-size: 60px;
}
.john-sass {
font-size: 48px;
}
<div class="img1">
<div class="container img1-container d-flex flex-column justify-content-center">
<h1 class="into-text web-dev"> Front-End Web Developer</h1>
<h4 class="into-text john-sass">John Sasser</h4>
</div>
</div>
It's just working fine with the align-items: center; You might not be able to notice it,
Here's the working example. Tell me if I have missed something
https://codepen.io/shivam1100/pen/yLymveb?editors=1100
I keep a 100% width and 100% view height
.img1{
width: 100%;
height:100%;
}
.img1-container{
height:100vh;
display: flex;
flex-direction:column;
align-items:center;
text-align: center;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet" />
<div class="img1">
<div class="container img1-container">
<h1 class="into-text web-dev">Front-End Web Developer</h1>
<h4 class="into-text john-sass">John Sasser</h4>
</div>
</div>
It was the height on the img1-container.....
Im guessing that adding the height property messes with the code behind the flexbox.

Flex div not render correctly

I've rows with two flex divs inside each one. In one div i show an image and inside the other there is text. I don't understand why some divs shows correctly but in others the text overflows.
If i reload the page this bug disappears but if i delete cache it comes again.
Any ideas? Thanks in advance.
.box {
position: relative;
}
.image-box-right, .image-box-left {
width: 50%;
}
.image-box-left {
float: left;
}
.image-box-right {
float: right;
}
.title {
font-size: 0.95em;
}
.text-box-right, .text-box-left {
background-color: #d53e73;
width: 55%;
height: 80%;
color: white;
box-sizing: border-box;
padding: 15px;
/* flex align items */
display: flex;
align-items: center;
justify-content: center;
font-size: 1.1em;
position: absolute;
margin-top: 5%;
top: 0;
right: 0;
}
.text-box-left {
left: 0;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet"/>
<div class="row box">
<div class="col-12 px-0">
<img class="image-box-right" src="img/image1.jpg">
<div class="text-box-left dark">
<p class="title"><span>Lorem Ipsum is simply dummy text of the printing and typesetting industry.</span>
<a href="../shared/note.html"> MORE <i class="fa fa-arrow-right"
aria-hidden="true"></i></a>
</p>
</div>
</div>
</div>
<div class="row box">
<div class="col-12 px-0">
<img class="image-box-left" src="img/image2.jpg">
<div class="text-box-right">
<p class="title"><span>Lorem Ipsum is simply dummy text of the printing and typesetting industry.</span>
<a href="../shared/note.html">MORE <i class="fa fa-arrow-right"
aria-hidden="true"></i></a>
</p>
</div>
</div>
</div>
I don't think you need inline-block:
.notes-text-box-right, .notes-text-box-left {
background-color: #d53e73;
width: 55%;
height: 80%;
color: white;
box-sizing: border-box;
padding: 15px;
/* flex align items */
display: flex;
align-items: center;
justify-content: center;
font-size: 1.1em;
position: absolute;
margin-top: 5%;
top: 0;
right: 0;
}
You wrote two displaysettings in one CSS rule:
.notes-text-box-right, .notes-text-box-left {
[...]
display: flex;
[...]
display: inline-block;
[...]
}
The second one overwrites the first one, so you better erase that.

How to text ellipsis overflow in table row with cell percentages

.container{
background-color: gray;
}
.listing-row{
display: table;
width: 100%;
margin 0;
}
.listing-row-inner{
display: table-row;
background-color: yellow;
}
.tc{
display: table-cell;
border: 1px solid black;
}
.listing-row-image{
width: 30%;
}
.listing-row-content{
width: 70%;
}
.stretch {
width : 40px;
overflow:hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.abs{
position: absolute;
right: 20px;
top:0px;
background-color: #0BB7A5;
display: block;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet"/>
<div class="row container">
<div class="col-sm-8">
<div class="listing-row">
<div class="listing-row-inner">
<div class="tc listing-row-image" >left</div>
<div class="tc listing-row-content">
<span class="stretch">
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
</span>
<span class="abs">AA</span>
</div>
</div>
</div>
</div>
<div class="col-sm-4"></div>
</div>
I Need to wrap the text in the right side respecting the left side and the column on the right in gray.
I have tried everything and searched on the internet, nothing seems to work.
I put min-width to the table-cell in the left side but then it takes space on the gray side.
add display:inline-block in stretch class and set your desire width
.container{
background-color: gray;
}
.listing-row{
display: table;
width: 100%;
margin 0;
}
.listing-row-inner{
display: table-row;
background-color: yellow;
}
.tc{
display: table-cell;
border: 1px solid black;
}
.listing-row-image{
width: 30%;
}
.listing-row-content{
width: 70%;
}
.stretch {
width : 40px;
overflow:hidden;
text-overflow: ellipsis;
white-space: nowrap;
display: inline-block;
}
.abs{
position: absolute;
right: 20px;
top:0px;
background-color: #0BB7A5;
display: block;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet"/>
<div class="row container">
<div class="col-sm-8">
<div class="listing-row">
<div class="listing-row-inner">
<div class="tc listing-row-image" >left</div>
<div class="tc listing-row-content">
<span class="stretch">
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
</span>
<span class="abs">AA</span>
</div>
</div>
</div>
</div>
<div class="col-sm-4"></div>
</div>

get image and caption into one flex item?

AI want to put an image and its caption into one flex-item and have several such flex-items in one flex-container. I want the image to be above its caption. But what happens is that each caption is beside its image. How do I get them one above the other?
I tried putting the captions into another flex-container below the images. But when the screen size is less wide, the images stack, then the captions stack instead of being image, then its caption, image, then its caption.
<div class="flex-item-popup" id="popup">
<div class="close"><i class="fa fa-2x fa-times-circle"></i></div>
<h2></h2>
<div class='text'></div>
<div class="videos"></div>
<div class="flex-container images"></div>
<div class="flex-container captions"></div>
</div>
css:
#popup {
width: 90%;
height: auto;
padding: 20px;
border-radius: 10px;
background-color: black;
color: white;
}
#popup .close {
/*position: absolute;
right: 10px;
top: 10px;*/
float: right;
color: white;
opacity: 1;
}
#popup .close:hover {
opacity: .7 !important;
}
.images, .captions {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: flex-start;
align-content: flex-start;
align-items: flex-start;
}
.images {
margin-top: 20px;
}
.images .flex-item, .captions .flex-item {
display: flex;
flex-grow: 0;
flex-shrink: 0;
flex-basis: 300px;
}
Look into <figure> and <figcaption> HTML5 tags. I am pretty certain that is going to help you and it is what you are looking for.
Here is updated fiddle link.
And the SO code snippet here...
.flex-container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
align-content: flex-start;
align-items: center;
}
.flex-item {
/*width: 350px;
height: null;*/
flex-grow: 1;
flex-shrink: 0;
flex-basis: 200px;
justify-content: flex-start;
display: flex;
padding-left: 20px;
}
.flex-item img {
cursor: pointer;
}
<div class="flex-container images">
<div class="flex-item">
<figure>
<img src="http://newsinteractive.post-gazette.com/hbcu/morehouse/img/grads.jpg" />
<!--<div style="clear: both;"></div>-->
<figcaption>Our grads.</figcaption>
</figure>
</div>
<div class="flex-item">
<figure>
<img src="http://newsinteractive.post-gazette.com/hbcu/morehouse/img/building.jpg" />
<figcaption>A building</figcaption>
</figure>
</div>
<div class="flex-item">
<figure>
<img src="http://newsinteractive.post-gazette.com/hbcu/morehouse/img/campus.jpg" />
<figcaption>The campus.</figcaption>
</figure>
</div>
<div class="flex-item">
<figure>
<img src="http://newsinteractive.post-gazette.com/hbcu/morehouse/img/trio.jpg" />
<figcaption>Three people</figcaption>
</figure>
</div>
</div>
Hope this helps

Resources