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>
Related
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>
I am trying to set three images in horizontal but the images always comes out vertically
I have took reference from internet but still I cant solve this problem can someone please help me how to set it horizontally
.categories{
margin: 70px 0;
}
.col-3{
flex-basis: 30%;
min-width: 250px;
margin-bottom: 30px;
}
.col-3 img{
width: 100%;
}
.small-container{
max-width: 1080px;
margin: auto;
padding-left: 25px;
padding-right: 25px;
}
<div class="categories">
<div class="small-container">
<div class="row">
<div class="col-3">
<img src="assets/offer.jpg">
<div class="col-3">
<img src="assets/offer2.jpg">
<div class="col-3">
<img src="assets/offer3.jpg">
</div>
</div>
if you are not using Bootstrap try this code
.categories{
margin: 70px 0;
}
.col-3{
flex-basis: 30%;
min-width: 250px;
margin-bottom: 30px;
}
.col-3 img{
width: 100%;
}
.small-container{
max-width: 1080px;
margin: auto;
padding-left: 25px;
padding-right: 25px;
}
.row{
flex-direction: row!important;
display:flex;
}
<div class="categories">
<div class="small-container">
<div class="row">
<div class="col-3">
<img src="assets/offer.jpg">
</div>
<div class="col-3">
<img src="assets/offer2.jpg">
</div>
<div class="col-3">
<img src="assets/offer3.jpg">
</div>
</div>
</div>
</div>
I list out some changes in your code
Close Every Divisions <div></div>
add row class like this
.row{
flex-direction: row!important;
display:flex;
}
if you are using bootstrap
Close Every Divisions <div></div>
add class in your HTML d-flex flex-row
like this
<div class="categories">
<div class="small-container">
<div class="d-flex flex-row">
<div class="col-3">
<img src="assets/offer.jpg">
</div>
<div class="col-3">
<img src="assets/offer2.jpg">
</div>
<div class="col-3">
<img src="assets/offer3.jpg">
</div>
</div>
</div>
</div>
The problem: I see you have used the flex-basis property. This property belongs to Flexbox and only works with Flex elements.
The solution:
You need to make .row a flex container like so:
.row {
display: flex;
}
By the way, your 2nd and 3rd col-3 don't have an ending tag. Please close them using an ending tag.
Some resources to learn Flexbox:
https://css-tricks.com/snippets/css/a-guide-to-flexbox/
https://flexboxfroggy.com
I am looking to achieve the following layout:
Here is how I'm picturing it (with grids):
Black bar is the nav (we can ignore this)
A title and subtitle (purple) - these should be aligned and take up approx 70% of width - I think I've done this
A form which has 3 columns (should take up 70ish percent of the 70%, I don't want inputs to be too wide)
Column 1: Heading + text pairs
Column 2: it will have some icon/character - these must be perfectly aligned
Column 3: Heading + input boxes - these must be the same width
Here is my starting HTML:
.title-container {
display: flex;
justify-content: center;
background: red;
}
.title-item {
flex-basis: 75%;
}
.data-container {
display: flex;
justify-content: center;
background: blue;
}
.column-items {
flex-basis: 70%;
display: flex;
flex-direction: row;
}
.column-1-item {
background: green;
flex-grow: 0.5;
}
.column-2-item {
background: yellow;
flex-grow: 0.1;
align-self: center;
}
.column-3-item {
background: orange;
flex-grow: 1;
}
<div class="title-container">
<div class="title-item">
<h2>Title</h2>
<p>This is some text</p>
</div>
</div>
<div class="data-container">
<div class="column-items">
<div class="column-1-item">
<p>Heading1</p>
<p>SomeText</p>
</div>
<div class="column-2-item">
<p>--></p>
</div>
<div class="column-3-item">
<p>Heading1</p>
<input type="text" name="lname">
</div>
</div>
</div>
I have tried to expand on this, but no matter what I try, I end up further away from my design making me think there is something wrong with my initial design (and flex understanding). If I add additional 'row', it breaks my layout. I also think my data-container is wrongly setup, since this will take up far more space than I want it to
Here is a code pen.
Could someone help get me closer to my design?
I would wrap your entire html in a wrapper class so that you can get the general layout of the page like so:
<div class="wrapper">
<div class="title-container">
<h2>Title</h2>
<p>
Subtitle should be aligned with title
</p>
</div>
<div class="form-container">
<div class="item">
<div class="column">
<p>Heading1</p>
<p>Some Text</p>
</div>
<div class="column">
<p>-></p>
</div>
<div class="column">
<p>Heading1</p>
<p>[ input textfield ]</p>
</div>
</div>
<div class="item">
<div class="column">
<p>Heading3</p>
<p>Some Text</p>
</div>
<div class="column">
<p>-></p>
</div>
<div class="column">
<p>Heading2</p>
<p>[ input textfield ]</p>
</div>
</div>
<div class="item">
<div class="column">
<p>Heading3</p>
<p>Some Text</p>
</div>
<div class="column">
<p>-></p>
</div>
<div class="column">
<p>Heading3</p>
<p>[ input textfield ]</p>
</div>
</div>
<div class="item">
<div class="column"></div>
<div class="column"></div>
<div class="column submit-button">
<p>[ Button ]</p>
</div>
</div>
</div>
</div>
Then you can specify the width for the title-container and form-container with the width property. Making each of the item classes in the form container have a display: flex property lets you format the children column classes to have flex-grow: 1 so they can fill up the available space. The css then looks like:
.wrapper {
display: flex;
flex-direction: column;
align-items: center;
outline: 1px solid red;
}
.title-container {
width: 70%;
outline: 1px solid red;
}
.form-container {
width: 50%;
outline: 1px solid red;
}
.item {
display: flex;
outline: 1px solid red;
}
.column {
/* flex-grow: 1; */
flex: 1 1 0px;
outline: 1px solid red;
}
.submit-button {
display: flex;
align-items: flex-end;
justify-content: flex-end;
}
Alternately you can remove the flex-grow: 1 property from the column class and add justify-content: space-between to the item class to get a result similar to your example.
Here is the codepen.
Your .data-container just needs a flex-direction: column; because you want the .column-items to stack.
I have to build a fluid, scalable, device-independent layout where I need to put 4 elements in a row so that they resize and stick together. Let’s say, 4 images, as they naturally are - one above another, and I just want to group them in two rows - 2 images side by side in 1 row so that I have no problems with layout or structure. Can you show me how? Thank you!
Use flexbox and make it responsive like this:
.element-container {
display: flex;
flex-direction: column;
width: 100%;
}
.element-row {
display: flex;
}
.element {
flex: 0 1 46%;
margin: 0 2% 20px 2%;
margin-bottom: 3%;
max-width: 150px;
}
.element img {
display: block;
width: 100%;
}
<div class="element-container">
<div class="element-row">
<div class="element">
<img src="http://via.placeholder.com/150x150">
</div>
<div class="element">
<img src="http://via.placeholder.com/150x150">
</div>
</div>
<div class="element-row">
<div class="element">
<img src="http://via.placeholder.com/150x150">
</div>
<div class="element">
<img src="http://via.placeholder.com/150x150">
</div>
</div>
</div>
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