My issue is that I have two (or more) divs of the same class, that need to be spaced from each other. I cannot directly use margins however, as the last or first element would also have the margin applied, which I do not want.
-Green is where I want the space
-Red is where I don't want it
As the only solutions I can think of are complicated / involve hard-coding a value, I am hoping that someone can think of a clever, simple solution to this problem.
Details: Sometimes these divs would be by themselves, and on a rare occasion floated.
Any advice on how above ideas could be better, any new ideas, or just help in general would be greatly appreciated ;)
You can try something like the following:
h1{
margin-bottom:<x>px;
}
div{
margin-bottom:<y>px;
}
div:last-of-type{
margin-bottom:0;
}
or instead of the first h1 rule:
div:first-of-type{
margin-top:<x>px;
}
or even better use the adjacent sibling selector. With the following selector, you could cover your case in one rule:
div + div{
margin-bottom:<y>px;
}
Respectively, h1 + div would control the first div after your header, giving you additional styling options.
If you don't require support for IE6:
h1 {margin-bottom:20px;}
div + div {margin-top:10px;}
The second line adds spacing between divs, but will not add any before the first div or after the last one.
Why not use margin? you can apply all kinds off margins to an element. Not just the whole margin around it.
You should use css classes since this is referencing more than one element and you can use id's for those that you want to be different specifically
i.e:
<style>
.box { height: 50px; background: #0F0; width: 100%; margin-top: 10px; }
#first { margin-top: 20px; }
#second { background: #00F; }
h1.box { background: #F00; margin-bottom: 50px; }
</style>
<h1 class="box">Hello World</h1>
<div class="box" id="first"></div>
<div class="box" id="second"></div>
Here is a jsfiddle example:
http://jsfiddle.net/baXmu/2/
REFERENCE:
http://www.html.net/tutorials/css/lesson10.php
DIVs inherently lack any useful meaning, other than to divide, of course.
Best course of action would be to add a meaningful class name to them, and style their individual margins in CSS.
<h1>Important Title</h1>
<div class="testimonials">...</div>
<div class="footer">...</div>
h1 {margin-bottom: 0.1em;}
div.testimonials {margin-bottom: 0.2em;}
div.footer {margin-bottom: 0;}
A slightly newer solution to this problem is to put the divs in a container that is display: flex or display: grid and to use the gap css property which will only add a space between elements inside the container, but not before/after.
flex solution:
.wrapper {
display: flex;
flex-direction: column;
gap: 20px;
}
header, footer {
background: red;
color: white;
}
<header>header</header>
<div class="wrapper">
<div>section 1</div>
<div>section 2</div>
<div>section 3</div>
</div>
<footer>footer</footer>
grid solution:
.wrapper {
display: grid;
grid-template-columns: 1fr;
gap: 20px;
}
header, footer {
background: red;
color: white;
}
<header>header</header>
<div class="wrapper">
<div>section 1</div>
<div>section 2</div>
<div>section 3</div>
</div>
<footer>footer</footer>
Related
I noticed that there is very little spacing between the AboutDogs and AboutCats divs. So I added some padding-top: 20px to the AboutCats to create some space between AboutDogs and AboutCats .
But let's say there is a scenario where I have only AboutCats and there is no other div on top of it. In that case, I don't want to add the padding-top: 20px since that will be unnecessary spacing on top.
<div class="MainContainer">
<main>
<div class="AboutDogs"></div>
<div class="AboutCats"></div>
</main>
</div>
Is there a way to address this scenario using CSS?
This is what the adjacent sibling selector is useful for.
You have some errors in your HTML code, by the way:
Don't have a space between class and the equals sign
Remember to close tags, as your main tag isn't closed
Here is an example of the adjacent sibling selector in use for you:
main {
background: lightgrey;
padding: 2em;
}
.about {
border: 1px solid red;
}
/*
* Adjacent sibling selector to add a top margin to any
* element with .about which follows another .about
*/
.about + .about {
margin-block-start: 1em;
}
<div class="main-container">
<main>
<div class="about about--dogs">Lorem</div>
<div class="about about--cats">Ipsum</div>
</main>
</div>
This is also very useful for setting up spacing on typography elements, such as paragraphs which follow another paragraph or a heading.
You also could have done this using CSS grid or flex, combined with the gap property. Here's an example:
main {
background: lightgrey;
padding: 2em;
display: grid;
grid-template-columns: 1fr;
gap: 1em;
}
.about {
border: 1px solid red;
}
<div class="main-container">
<main>
<div class="about about--dogs">Lorem</div>
<div class="about about--cats">Ipsum</div>
</main>
</div>
One modern solution which also is redundant for all potential cases is the usage of Flexbox. Change the flex-direction to column to maintain the normal block-level behavior. You can space apart elements within Flexbox by using the gap property.
main {
display: flex;
flex-direction: column;
gap: 20px;
}
/* for visualization only */
main > div {
border: 2px dashed red;
}
<div class="MainContainer">
<main>
<div class="AboutDogs">About Dogs</div>
<div class="AboutCats">About Cats</div>
</main>
</div>
An Alternative is the usage of the :nth-child() selector. With n+2 you can select all child elements starting from the 2nd element.
main > div:nth-child(n + 2) {
margin-top: 20px;
}
/* for visualization only */
main > div {
border: 2px dashed red;
}
<div class="MainContainer">
<main>
<div class="AboutDogs">About Dogs</div>
<div class="AboutCats">About Cats</div>
</main>
</div>
This question already has answers here:
Targeting flex items on the last or specific row
(10 answers)
Closed 3 years ago.
The inner divs will be thumbs that are being continuously added and eventually wrap to next row.
The space between divs should be 20px.
I want four divs in one row.
Two constraints:
Ideally no flexbox space-between, due to last row looking weird with only two divs.
Adding margin only between inner divs not a good option (unless there’s an easy way to do this for dynamically added content?).
Is there a way to accomplish this?
#outer {
width: 460px;
display: inline-block;
}
.inner {
width: 100px;
height: 100px;
float: left;
}
<div id="outer">
<div class="inner">1</div>
<div class="inner">2</div>
<div class="inner">3</div>
<div class="inner">4</div>
</div>
Codepen example
Try this. Hope, it will work.
I used the CSS grid. By using grid-template-columns, I have declared how four children elements of outer ID take the same area in a row. After that, I used grid-gap: 20px for giving space between four children block.
#outer {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-gap: 20px;
}
You can use this code:
.inner {
display: inline-block;
}
.inner:not(:last-child){
margin-right: 20px;
}
<div id="outer">
<div class="inner">1</div>
<div class="inner">2</div>
<div class="inner">3</div>
<div class="inner">4</div>
</div>
Read a reference here: css-protips
You may need to use nth-child(4n)
.inner {
margin-right: 20px;
}
.inner:nth-child(4n){
margin-right:0px;
}
Codepen: https://codepen.io/abozanona/pen/RwbqmZb
You could use a margin and avoid the last one:
.inner:not(:last-of-type) {
margin-right: 20px;
}
have a css float problem that i'm not sure how to fix or best way to fix and can't seem to find anything in searches. I have a variable amount of items to show inside a div, using a css float left on all the inner boxes (1, 2, and 3 in pic) but the float breaks with variable lines of text. the developer outlines show that because box 1 is larger that box 2, box 3 doesn't float flush left like box 1 which screws up the flow. how do i keep the vertical height of box 1 and box 2 but make box 3 float left where it should be? Doing a float: right; does the same thing but just pushes 3 to the left is div 2 is larger than div 1
This is just an example, there could be a variable number of rows and columns so just doing an Nth div css rule won't work. (the containing div is a variable width based on a few conditions including responsive design)
Almost like i have to have a variable buffer at the bottom of each item in a row to match the height of the tallest one. I also don't want to use a min-height as on rows where the divs are the same height will result in extra white space where there shouldn't be. How would i get the tallest element in a row if the number of columns are variable?
A possible solution is to use the empty clearing div trick but again how do I get the number of divs in a row when columns are variable? I tried to force a nth child::after thing in the example but it didn't work
.item:nth-child(2)::after {
clear: both;
}
Search didn't show anything that works so if anyone has a post that does please let me know.
also have to stick with CSS2 if at all possible due to a bunch of users using older browsers that don't use CSS3
One solution is to use display:inline-block for the figures rather than float:left.
.figure {
display: inline-block;
vertical-align: top;
margin: 2px 1em;
border:1px solid grey;
}
.figcaption {
margin:1em;
}
<div class="section">
<div class="figure">
<img src="http://placehold.it/250x250" alt="#">
<div class="figcaption">
Line 1<br/>Line 2
</div>
</div>
<div class="figure">
<img src="http://placehold.it/250x250" alt="#">
<div class="figcaption">
Line 1
</div>
</div>
<div class="figure">
<img src="http://placehold.it/250x250" alt="#">
<div class="figcaption">
Line 1<br/>Line 2
</div>
</div>
</div>
You need to clear:both the 3rd element actually in this case.
See solution below.
img {
width:50%;
float:left;
}
img:nth-child(3) {
clear: both;
}
<img src="http://via.placeholder.com/350x160">
<img src="http://via.placeholder.com/350x150">
<img src="http://via.placeholder.com/350x150">
If you got some complex example please provide jsfiddle.
that's because your <div>s are styled with "float" and 3rd div has floated to 1st, because 1st is taller than others.
Possible solutions (not including the hardcoding - it's like a deadly sin):
Give equal height to each item in a set
.float {
background-color: #f90;
float: left;
height: 100px;
line-height: 100px;
margin: 10px;
text-align: center;
width: calc(50% - 20px);
}
<div class="float">float 1</div>
<div class="float">float 2</div>
<div class="float">float 3</div>
Use different approach, such as flexbox
.wrapper {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
}
.flex {
background-color: #f90;
height: 100px;
line-height: 100px;
margin: 10px;
text-align: center;
width: calc(50% - 20px);
}
<div class="wrapper">
<div class="flex" style="height: 120px;">flex 1</div>
<div class="flex">flex 2</div>
<div class="flex">flex 3</div>
</div>
I have a page layout with the following html structure:
<div class="row">
<div class="col3">test 1</div>
<div class="col3">test 2</div>
<div class="col3">test 3</div>
</div>
Using the following css, I wanted to make a simple, responsive layout:
.row {
width: 100%;
display: block;
padding-left: 1.25%;
padding-right: 1.25%;
margin: 0 auto 15px auto;
}
.col3 {
width: 30%;
display: inline-block;
margin: 0 1.25%;
border: none;
}
Why is it when I shrink my page to 30% of the width of my screen, the last column drops down underneath the other rows?
Is there something im not accounting for? I would have thought it would have just continued to get narrower and narrower. What causes it to create a content break, and drop down a row.
Screenshots:
It's from display: inline-block. If you float your columns to the left they will work as expected.
When you use display: inline-block spaces/returns etc between the elements that have inline-block applied to them will be taken into account and rendered. You can think of it as adding a single space between each inline-block element.
This is the main downside of using display: inline-block over floats in my humble opinion.
.col3 {
float: left;
width: 30%;
margin: 0 1.25%;
border: none;
}
You could also remedy this by doing the following if you wanted to continue using display: inline-block but they're hackerish. I would advise against either of these solutions.
no space between elements
<div class="col3">test 1</div><div class="col3">test 1</div><div class="col3">test 1</div>
comments between elements
<div class="col3">test 1</div><!--
--><div class="col3">test 1</div><!--
--><div class="col3">test 1</div>
Your problem lies with the lines
.col3 {
..
width:30%;
margin: 0 1.25%;
..
}
As width is 30% of the row, but while you are narrowing it down, the margin is actually getting wider with respect to the row, its a common thing which happens to inline-block display type.
If you drop the margin line, or simply change the width of the margin to
margin: 0 1%;
it would be fixed.
No need to worry about fixing inline-blocks, or having to deal with its downsides.
I'm looking for a CSS solution to the following:-
<div style="display:inline;">
<div>The content of this div is dynamically created but will always be wider than
the below div.
</div>
<div> Need this div to have the same width as the above div.
</div>
</div>
The wrapper div has an inline display and works as expected, both child divs have dynamically generated content. I need the bottom one to take the width of the previous sibling.
Many thanks for any suggestions in advance.
Here's another Flexbox solution which allows for the second child to wrap to match the width of the variable height sibling.
.wrapper > div {
border: 1px solid;
}
.child {
display: flex;
}
.child div {
flex-grow: 1;
width: 0;
}
.wrapper {
display: inline-block;
}
<div class="wrapper">
<div>This div is dynamically sized based on its content</div>
<div class="child"><div>This div will always be the same width as the preceding div, even if its content is longer (or shorter too).</div></div>
</div>
Edit:
To support multiple divs under .child, where each div is on its own line, add break-after: always; ...
.child div {
flex-grow: 1;
width: 0;
break-after: always;
}
Floats and tables are so 2000 and late. With today's browsers we can make the two sibling DIVs match each other's width, regardless which is bigger/smaller.
Here's a Flexbox solution fit for 2016:
.wrapper {
display: inline-block;
}
.parent {
display: flex;
flex-direction: column;
}
/* For visualization */
.child {
border: 1px solid #0EA2E8;
margin: 2px;
padding: 1px 5px;
}
<div class="wrapper">
<div class="parent">
<div class="child">Child number one</div>
<div class="child">Child #2</div>
</div>
</div>
Set your div to display:inline-block instead, this way your div will expand with the content inside of it.
http://jsfiddle.net/CpKDX/
2023 keep it simple...
Use grid and the fr unit. Then you can split up into as many equally sized rows or columns as you want:
.container {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-column-gap: 1em;
}
.container > div {
border: 1px solid black;
padding: 0.5em;
}
<div class="container">
<div>I'm a part of a grid. I will be split up into equal parts with my other sibling(s) depending on how many columns the grid is given.</div>
<div>I am a sibling element.</div>
</div>
Here is still a flexbox-based approach.
The essential idea: in an outermost wrapper, elements that need to be of equal width are wrapped into another wrapper.
.wrapper {
display: inline-block;
}
.flex-wrapper {
display: flex;
flex-direction: column;
}
.demo-bar {
height: 4px;
background-color: deepskyblue;
}
<div class="wrapper">
<div class="flex-wrapper">
<div contenteditable>Some editable text.</div>
<div class="demo-bar"></div>
</div>
</div>
Another practical example: an adaptive progress bar with the same width below a media (video or audio) element.
video.addEventListener("timeupdate", () =>
progress.style.width = `${video.currentTime / video.duration * 100}%`
)
.wrapper {
display: flex;
flex-direction: column;
position: relative;
align-items: center;
}
video {
display: block;
max-width: 100%;
}
.progress-bar {
height: 0.25rem;
background: #555;
}
#progress {
width: 0%;
height: 100%;
background-color: #595;
}
<div class="wrapper">
<div data-css-role="wrapper">
<video id="video" controls>
<source src="https://raw.githubusercontent.com/mdn/interactive-examples/master/live-examples/media/cc0-videos/flower.webm">
</video>
<div class="progress-bar">
<div id="progress"></div>
</div>
</div>
</div>
UPDATE: This works with me, I've just tried it:
<div style="max-width:980px;border:1px solid red;">
<div style="background:#EEE;float:left;">
<div style="width:auto;border:1px solid blue;float:left;">If you use 100% here, it will fit to the width of the mother div automatically.</div>
<div style="border:1px solid green;"> The div will be 100% of the mother div too.</div>
</div>
<div style="clear:both;"></div>
</div>
Is this what you want? The borders and background are just to show the divs ;)
Just go like this:
Let's say you want the whole divs be max. 980px (otherwise just leave that out or replace with 100%)...
<div style="max-width:980px;">
<div style="width:100%;">If you use 100% here, it will fit to the width of the mother div automatically.
</div>
<div style="width:100%;"> The div will be 100% of the mother div too.
</div>
</div>
The second option would be, to use one more div... or you use style="width:auto;" for the dynamic div...
Not sure if I understood what you are trying to do, but looks like setting a 100% width to the last div should work:
<div style="width:100%;">
BTW the style in the first div is not well defined, you should use a colon instead of a equal sign in the properties definition:
<div style="display:inline;">
If your willing to give up on a couple of <div>s then I have the solution for you:
<div style=“display: inline-block;”>
<table>
<tr>
<td>The table automatically makes its siblings the same width</td>
</tr>
<tr>
<td>So this will be as wide</td>
</tr>
</table>
</div>
Remember to set the div display:inline-block;