Divs with same class adjust to different content - html

I have three divs in a row next to each other. They have the same class and same structure, but their content is different, particularly in length.
My problem is, that all three divs take the height of the one with the "longest" content instead of adjusting to their individual content.
Here's my HTML:
<main class="content">
<div class="column last-match">
<div class="image-wrapper">
<img src="default_thumbnail.jpg"/>
</div>
<div class="text-wrapper">
<a class="heading" href="#"><p class="heading">A Heading</p></a>
<p class="post-excerpt">Some text</p>
Read More
</div>
</div>
<div class="column last-match">
<div class="image-wrapper">
<img src="default_thumbnail.jpg"/>
</div>
<div class="text-wrapper">
<a class="heading" href="#"><p class="heading">A Heading</p></a>
<p class="post-excerpt">Some text that's longer</p>
Read More
</div>
</div>
<div class="column next-matches">
<div class="image-wrapper">
<img src="next_matches.jpg"/>
</div>
<div class="text-wrapper">
<p class="heading">List Heading</p>
<ul class="match-list">
<li class="match">some list item</li>
<li class="match">some list item</li>
</ul>
</div>
</div>
</main>
And the basic CSS:
.content {
display: flex;
flex-wrap: nowrap;
}
.column {
display: flex;
flex-direction: column;
margin: 60px 20px;
min-height: 100px;
width: 33%;
}
.image-wrapper {
width: 100%;
height: 260px;
overflow: hidden;
}
.image-wrapper img {
width: 100%;
height: auto;
}
.post-excerpt {
margin-bottom: 20px;
}
.button {
display: block;
float: left;
margin-bottom: 20px;
padding: 10px;
}
.match {
font-size: 1em;
padding-top: 15px;
}
Here's my code on JSFiddle: https://jsfiddle.net/4h0g73sp/5/
As you will see, the columns will take the height of the one with the most text in it. What I want is them to adjust to their content, so that they have different heights if necessary.
I don't know if it's noteworthy, that I'm working with Wordpress, so these columns are originally inside of some php. If that's important I'm happy to share the code with you, so let me know :)

The issue is because align-items on the flex container defaults to stretch so the flex items takes the height (rows) of the tallest item.
Simply set it to flex-start
.content {
display: flex;
align-items: flex-start;
}
https://jsfiddle.net/4h0g73sp/9/
I have also removed flex-wrap from .content because the default is no wrap so there is no need to declare it
Check https://css-tricks.com/snippets/css/a-guide-to-flexbox/ it's very useful and demonstrates flex fairly well

Related

How do I align 3 div container next to each other using CSS when float left does not work

I am trying to align my 3 service divs next to each other but instead they are each slightly lower than the other one. I think it might be the images that are making so they do not align. I have tried the following without success:
.col-md-4 {
float:left;
}
Please advise what I am doing wrong and how I can align my divs, my code is as follows:
HTML
<section id="services">
<div class="container text-center">
<h1 CLASS="title">WHAT WE OFFER</h1>
<div class="row text-center">
<div class="col-md-4 services">
<img src="images/service1.png" class="service-img">
<h4>TITLE 1</h4>
<p>Add sentence here not sure what to say just yet but has to be good</p>
</div>
<div class="col-md-4 services">
<img src="images/service2.jpg" class="service-img">
<h4>TITLE 2</h4>
<p>Add sentence here not sure what to say just yet but has to be good</p>
</div>
<div class="col-md-4 services">
<img src="images/service3.png" class="service-img">
<h4>TITLE 3</h4>
<p>Add sentence here not sure what to say just yet but has to be good</p>
</div>
</div>
<button type="button"class="btn btn-primary"> All Services</button>
</div>
</section>
CSS
#services
{
padding: 80px 0;
}
.service-img
{
width: 100px;
margin-top: 20px;
}
.services
{
padding: 20px; /*service images and paragraphs do not want to align*/
}
.services h4
{
padding: 5px;
margin-top: 25px;
text-transform: uppercase;
}
.title::before
{
content: '';
background: #7b1798;
height:5px;
width: 300px;
margin-left: auto;
margin-right: auto;
display: block;
transform: translateY(63px);
}
#services .btn-primary
{
box-shadow: none;
padding: 8px 25px;
border: none;
border-radius: 20px;
background-image: linear-gradient(to right,#a517ba,#5f1782);
Instead of using the default flow layout, the flexbox layout can help you in this situation. CSS Tricks have a great guide about it here.
Applying display: flex to the parent div .row would render its children divs .services in the flexbox layout. Further, applying the CSS declaration align-items: center; should horizontally align its children elements .services in a single line.
The full CSS rule could be:
.row {
display: flex;
align-items: center;
}

How to set identical gap between elements when one image is longer than rest

I will put here some code for better understanding my need.
.wrap{
display:flex;
flex-direction:row;
align-items: center;
justify-content: flex-start;
width: 100%;
}
.img{
width: 30px;
height: 20px;
background: red;
}
.img1{
width:40px;
}
<div class='wrap'>
<div class='img img1'>
</div>
<p>
Xxxxxxxxxxxxx
</p>
</div>
<div class='wrap'>
<div class='img'>
</div>
<p>
yyyyyyyyy
</p>
</div>
<div class='wrap'>
<div class='img'>
</div>
<p>
zzzzzz
</p>
</div>
So as u can see, we have 3 div & p elements. I want to separate this elements with identical gap between them. I want separate red div from text. As u notice, first element is longer than rest. I wouldn't like to use static margin or padding value. Exist better solution?
You need a container that defines the width of all children. Then, you can set justify-content: space-between on .wrap, so the text and the red rectangle will get away from each other.
Then, add a gap property to .wrap, so you'll have a basic gap between the elements to start with.
Here's your snippet with the new adjustments:
.container {
display: flex;
flex-direction: column;
max-width: fit-content;
}
.wrap {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
gap: 1em;
width: 100%;
}
.img {
width: 30px;
height: 20px;
background: red;
}
.img1 {
width: 40px;
}
<div class="container">
<div class='wrap'>
<div class='img img1'>
</div>
<p>
Xxxxxxxxxxxxx
</p>
</div>
<div class='wrap'>
<div class='img'>
</div>
<p>
yyyyyyyyy
</p>
</div>
<div class='wrap'>
<div class='img'>
</div>
<p>
zzzzzz
</p>
</div>
</div>

How do I fill the remainder of the visible page with a background color?

I have a page I'm trying fill some content with and then the remainder of the page fill with a background color. I've kind of been able to achieve this using min-height: 100vh but the problem is now my page scroll get's extended significantly. Is it possible just to color the visible space on the screen without increasing scrollable area on the page.
Here's a simple example with a jsfiddle:
If you remove the min-height: 100vh from .footer notice that the colored square gets much smaller and now the scroll area isn't very large either. How do I only fill that area that's visible when not using the min-height style.
.body {
margin-left: 50px;
}
.footer {
background-color: grey;
min-height: 100vh;
z-index: -100;
margin-top: -150px;
}
img {
z-index: 100;
margin-left: 200px;
}
h1 {
text-align: center;
}
<div class="body">
<div class="row justify-content-center text-centerr">
<h1>
This is my page heading
</h1>
</div>
<div class="row justify-content-center text-center">
<p>
This is some information about this page.
</p>
</div>
<div class="row justify-content-center text-centerr">
<div class="justify-content-center">
<img src="https://cdn.vox-cdn.com/thumbor/RkBHz5tPuCNQOG0a6FooNwiqQyw=/0x0:939x704/1820x1213/filters:focal(0x0:939x704):format(webp)/cdn.vox-cdn.com/uploads/chorus_image/image/49610677/homersimpson.0.0.jpg"
width="300px"
height="300px"
</div>
</div>
<div class="footer">
<br />
</div>
</div>
This is what I came up with, using flexbox and flex-grow: 1 to force the element to grow and take up the remaining space and flex-shrink: 0 to prevent the img and other elements from shrinking.
I had to add a new class to he footer's parent element, to add the flexbox class to it. note the footer-parent class.
<div class="body">
<div class="row justify-content-center text-center">
<h1>
This is my page heading
</h1>
</div>
<div class="row justify-content-center text-center">
<p>
This is some information about this page.
</p>
</div>
<div class="row footer-parent justify-content-center text-center">
<div class="justify-content-center">
<img src="https://cdn.vox-cdn.com/thumbor/RkBHz5tPuCNQOG0a6FooNwiqQyw=/0x0:939x704/1820x1213/filters:focal(0x0:939x704):format(webp)/cdn.vox-cdn.com/uploads/chorus_image/image/49610677/homersimpson.0.0.jpg" width="300px" height="300px" />
</div>
<div class="footer">
<br />
</div>
</div>
</div>
Here's the CSS
body {
margin: 0;
}
.body {
display: flex;
flex-flow: column nowrap;
margin-left: 50px;
height: 100%;
min-height: 100vh;
}
.footer {
background-color: grey;
flex-grow: 1;
z-index: -100;
margin-top: -150px;
}
.footer-parent {
display: flex;
flex-grow: 1;
flex-flow: column nowrap;
}
img {
z-index: 100;
flex-shrink: 0;
margin-left: 200px;
}
h1 {
flex-shrink: 0;
text-align: center;
}

Element alignment: Remove margin with modifier class not working

I have a wrapper with two boxes in it. The boxes are each to other. In the boxes there is a title (optional) and a content. I have two cases. First case: One of the boxes has a title the other hasn't. Second case: Both boxes have a title. If you take a look on the example for the second case (both titles), the boxes and titles are aligned on the bottom of the wrapper, and the titles are also aligned. There is also an example for the first case (one box without title). Because of the missing title, the alignment isn't correct yet. Here is a screenshot of the problem:
So what I tried is, to figure out the missing space for the first case, which was 21px. After this I select in CSS the second box and add the missing space. For the second case with both title, I tried to add a modifier class on the box and remove the margin-top. So default there would be a space on the second box if no title (this title is optional) and if both titles are avalable, a class should remove it again. Thats the part of the code:
.box + .box {
margin-top: 21px;
}
.box--with-title {
margin-top: 0;
}
Now with my idea it doesn't work. The first case is solved, but my class is not removing the margin. So now the alignment for the second case is wrong. Any ideas how to solve that the class is removing the margin or is there a bether way to do this with pure CSS? Hope this is clear enough.
.wrapper {
display: flex;
justify-content: space-betweet;
width: 500px;
background-color: lightgray;
;
margin-top: 36px;
}
.box {
display: flex;
flex-direction: column;
width: 50%;
}
.box__content {
width: 120px;
height: 100px;
background-color: lightcoral;
}
.box+.box {
margin-top: 21px;
}
.box--with-title {
margin-top: 0;
}
<div class="wrapper">
<div class="box">
<h3>I have a title!</h3>
<div class="box__content"></div>
</div>
<div class="box">
<h3></h3>
<div class="box__content"></div>
</div>
</div>
<div class="wrapper">
<div class="box">
<h3>I have a title!</h3>
<div class="box__content"></div>
</div>
<div class="box box--with-title">
<h3>I have also a title!</h3>
<div class="box__content"></div>
</div>
</div>
Simply use align-items:flex-end on the container and no need to consider margin:
flex-end
The cross-end margin edge of the flex item is flushed with
the cross-end edge of the line. ref
.wrapper {
display: flex;
justify-content: space-between;
align-items:flex-end;
width: 500px;
background-color: lightgray;
;
margin-top: 36px;
}
.box {
display: flex;
flex-direction: column;
width: 50%;
}
.box__content {
width: 120px;
height: 100px;
background-color: lightcoral;
}
<div class="wrapper">
<div class="box">
<h3>I have a title!</h3>
<div class="box__content"></div>
</div>
<div class="box">
<div class="box__content"></div>
</div>
</div>
<div class="wrapper">
<div class="box">
<h3>I have a title!</h3>
<div class="box__content"></div>
</div>
<div class="box box--with-title">
<h3>I have also a title!</h3>
<div class="box__content"></div>
</div>
</div>
By the way your intial code was almost good, you are simply facing a specificity issue which make the rule of .box--with-title not being considered. You may do something like this instead:
.wrapper {
display: flex;
justify-content: space-betweet;
width: 500px;
background-color: lightgray;
;
margin-top: 36px;
}
.box {
display: flex;
flex-direction: column;
width: 50%;
}
.box__content {
width: 120px;
height: 100px;
background-color: lightcoral;
}
.box+.box {
margin-top: 21px;
}
.box.box--with-title {
margin-top: 0;
}
<div class="wrapper">
<div class="box">
<h3>I have a title!</h3>
<div class="box__content"></div>
</div>
<div class="box">
<h3></h3>
<div class="box__content"></div>
</div>
</div>
<div class="wrapper">
<div class="box">
<h3>I have a title!</h3>
<div class="box__content"></div>
</div>
<div class="box box--with-title">
<h3>I have also a title!</h3>
<div class="box__content"></div>
</div>
</div>

Flexbox many nested children

I've read many posts on flexbox but still have an issue that bugs me.
I want to have a sticky footer using flexbox as per this guide.
But then, inside my page content I would like to have as many nested divs I like and have them taking the same height of the parent.
The problem is, setting height: 100% on each child (as I would do in a non-flexbox scenario) works differently when flexbox is enabled. This results in the children getting more height (overflow the parent).
To make this more clear here's a codepen without flexbox
and a codepen with flexbox
You can see in the flexbox scenario the footer gets the green bakground even if I don't want that.
HTML:
<div class="sticky-footer-container">
<div class="sticky-footer-content">
<div class="page-container">
<div class="main-menu">
<div class="main-menu-selection">
<div class="main-menu-selection-text">
<div class="some-other-class">
Some text
</div>
</div>
</div>
<div class="main-menu-selection">
<div class="main-menu-selection-text">
<div class="some-other-class">
Some text
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sticky-footer">
Some footer content
</div>
</div>
SCSS:
* {
box-sizing: border-box;
}
html,
body {
height: 100%;
background: silver;
padding: 0;
margin: 0;
}
.sticky-footer-container {
height: 100%;
display: flex;
flex-direction: column;
.sticky-footer-content {
height: 100%;
background: blue;
flex: 1;
div {
height: 100%;
}
.main-menu-selection {
height: 50%;
}
}
}
.some-other-class {
background: green;
}
In order to solve this, ANY nested div has to become a flex-container ?
In other words, is there any way to "stop the flex propagation" at some point of the tree, so all the divs gets the parent height without overflow?
display:flexbox is not really a valid value :)
you need to set height as well and eventually inherit it from html :
.sticky-footer-container {
display: flex;
flex-direction: column;
}
.sticky-footer-content {
flex: 1;
}
/* let's inherit some height to pull the footer down */
html,
body,
.sticky-footer-container {
height: 100%;
margin: 0;
}
.sticky-footer {
display: flex;/* flex item can be flexboxes as well */
background: turquoise;
align-items: center;
justify-content: center;
min-height: 3em;
}
<div class="sticky-footer-container">
<div class="sticky-footer-content">
<div class="page-container">
<div class="main-menu">
<div class="main-menu-selection">
<div class="main-menu-selection-text">
<div class="some-other-class">
Some text
</div>
</div>
</div>
<div class="main-menu-selection">
<div class="main-menu-selection-text">
<div class="some-other-class">
Some text
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sticky-footer">
Here my footer
</div>
</div>