Center blocks/divs horizontally and allow them to stack inline - html

I've got divs that are a fixed width and height and display in a row. The problem comes when I'm trying to make it responsive. I need the divs to stack in a row underneath eachother.
I made a fiddle http://jsfiddle.net/h657t6r2/1/ so you can see. If you play around with the width of the content window, you'll see the blocks stack but the 4th one then stacks underneath the 2nd one because it is center aligned. I want it to be center aligned because without it it leaves a big gap on the right and doesn't look good. A similar sort of stacking as on https://www.behance.net, except they never have a situation like mine where there's leftover blocks.
What I need is for the 4th block to stack neatly underneath the 1st block when the screen gets smaller and they stack.
FYI: The number of blocks is dynamic, it's not always 4.
<div class="content">
<div class="course_list">
<div class="box coursebox">
</div>
<div class="box coursebox">
</div>
<div class="box coursebox">
</div>
<div class="box coursebox">
</div>
</div>
</div>
.coursebox{
border: green 1px solid;
padding:10px;
width: 90px;
height: 90px;
margin: 0 20px 20px 20px;
display: inline-block;
}
.content{
text-align: center;
}
.course_list{
display: inline-block;
}

Per my comment
Since your blocks are fixed width anyway, you can center course_list and leave the blocks inside of it left aligned. Give course_list a width at different break points (media query) to have the ideal number of boxes per row. This is a cross browser solution
Here is an example of simplified version of what you had
http://jsfiddle.net/h657t6r2/2/
.coursebox{
border: green 1px solid;
box-sizing: border-box;
width: 100px;
height: 100px;
margin: 0 20px 20px 20px;
display: inline-block;
}
.course_list{
margin: 0 auto;
width: 560px;
}
#media (max-width: 559px) {
.course_list{
margin: 0 auto;
width: 280px;
}
}
As you can see I only have one break point for simplicity. You can put in as many as you need. Also note I got rid of the space in between your block's closing/opening tags to avoid the extra space when using display inline block
OR
You can have something even simpler like
http://jsfiddle.net/h657t6r2/3/
Set a % width for the centered container and let the blocks fall naturally
.coursebox{
border: green 1px solid;
box-sizing: border-box;
width: 100px;
height: 100px;
margin: 0 20px 20px 20px;
display: inline-block;
}
.content{
}
.course_list{
margin: 0 auto;
width: 80%;
}

Related

Why does inline-block does not make div inline? [duplicate]

This question already has answers here:
Two divs side by side - Fluid display [duplicate]
(9 answers)
Closed 2 years ago.
I wanted to make an inline div using inline-block, but it doesn't work and either turns it turns one of the two divs below and the other above
#div-on-the-left {
background-color: #464886;
width: 200px;
height: 600px;
padding: 10px;
border: 10px double #2c2d54;
margin: 5px;
}
#big-div-on-the-right {
background-color: #AAABB8;
width: 600px;
height: 600px;
display: inline-block;
margin: 5px;
}
<div id="div-on-the-left">
<!--Some html-->
</div>
<div id="big-div-on-the-right">
<!--Some html-->
</div>
I also tried giving #div-on-the-left inline-block too, that brought #big-div-on-the-right above, but left a gap where #div-on-the-left was supposed to be and brought #div-on-the-left to the bottom, why is this happening?
YOu would be way better off using a grid or flexboxes. In this case flexboxes would be "easier" and "shorter". You main issue is, that both div-boxes have a different height. The left div-box have a height of 600px + (2x20px) = 640px because of the double border. the right div-box have a height of only 600px causing different line height and therefor will cause a line-break. Next, the minimum-width has to be set large enough to allow both boxes to be displayed next to each other.
In the snippet below, I wrapped both boxes inside a wrapper with a minimum width high enough to let them be displayed next to each other. Then I changed them to display: flex;.
The height for the right box was set to 640px becaue of the border mentioned above.
.wrapper {
min-width: 850px;
display: flex;
}
#div-on-the-left {
background-color: #464886;
width: 200px;
height: 600px;
padding: 10px;
border: 10px double #2c2d54;
margin: 5px;
}
#big-div-on-the-right {
background-color: #AAABB8;
width: 600px;
height: 640px;
margin: 5px;
}
<div class="wrapper">
<div id="div-on-the-left">
<!--Some html-->
</div>
<div id="big-div-on-the-right">
<!--Some html-->
</div>
</div>

How to do CSS column layout with a "floating" object spanning multiple columns?

I'd like to create a layout in CSS that looks something like this:
+----------------+ __5_____
| | __6_____
| | __7_____
| | __8_____
+----------------+ __9_____
___1____ __3_____ __10____
___2____ __4_____
Basically, the text (in the above diagram, the lines labelled 1 through 10) are arranged in a three-column layout, with a block (image, or whatever) sitting in the top left, occupying two columns, displacing the text.
Importantly, I'd REALLY like to avoid manually specifying where the column breaks are, because the content is user-provided. I have been using the CSS columns family of properties (column-width, column-count, etc.) to get the column layout for the text, but I'm not having much success putting the big floating block where I want. Is there a way to do this that doesn't involve a pile of JS to compute the optimal column break locations, and generating the columns myself?
Edited to add: in case it's not clear, in this example there are 10 rows but in practice I need to be able to deal with an arbitrary number of rows and still get columns of roughly equal height.
You can try setting your image div width to 66% of the container, and add padding in both sides to align it with the white space between the columns:
.div-with-image {
width: 66%; // 2/3 of the container
padding: 0 20px; // assuming 20px gutters for the columns
}
UPDATE
As the current state of the CSS Multi-column Module, the only "natural" alternatives to make an image span through several columns is either through the column-span property or overflowing the image inside the column.
However, column-span doesn't support -yet- other values than none (default) and all, and the overflow won't displace the text in the next columns but would just cover it or will be clipped by the containing column (depending on the browser).
The cleanest solution that comes to my mind:
Absolute position your image to the top left corner and define its width to span 2 columns, set the top margin of the first paragraph to the height of your image and insert a break before a dummy element (just a placeholder, could be a span) identified with a class. Finally, as that dummy element will be in the first line of the second column, you can assign the same margin top as you did with the first paragraph of the first column.
#image-placeholder {
width: 600px;
height: 200px;
background-color: lightgreen;
position: absolute;
top: 0;
left: 0;
}
#columnized {
-moz-column-width: 300px;
column-width: 300px;
position: relative;
}
#columnized p:nth-child(2) { // the image is the first child
margin-top: 200px;
}
.break { // your dummy element (I used a span)
break-before: always;
display: inline-block;
margin-top: 214px; // I had to tweak the margin a little
}
Additional notes
I know that you made your snippet as simple and possible, but, just in case: remember to add p tags and make it responsive (best practices). You may want to set the height of the #columnized div to use the same break across different screen sizes.
You could just do a simple two column layout and split one in half where needed.
JSFiddle
/* 2 column grid */
.gridWrapper {
width: 80%;
float: none;
margin: 0 auto;
margin-top: 50px;
margin-bottom: 50px;
}
.column {
float: left;
width: 50%;
padding: 10px;
box-sizing: border-box;
}
.column img {
width: 100%;
max-width: 400px;
height: auto;
margin: 0 auto;
display: block;
padding: 10px;
box-sizing: border-box;
}
.column p {
float: left;
width: 100%;
padding: 10px;
margin: 0 0 5px;
box-sizing: border-box;
text-align: center;
border: 1px solid gray;
}
.left, .right {
border: 1px solid blue;
}
.split {
float: left;
width: 50%;
padding: 10px;
box-sizing: border-box;
text-align: center;
border: 1px solid red;
}
<div class="gridWrapper">
<div class="column left">
<div class="image">
<img src="http://c.shld.net/rpx/i/s/i/spin/image/spin_prod_709722401??hei=64&wid=64&qlt=50">
</div>
<div class="split">
<p>1</p>
<p>2</p>
</div>
<div class="split">
<p>3</p>
<p>4</p>
</div>
</div>
<div class="column right">
<p>5</p>
<p>6</p>
<p>7</p>
<p>8</p>
<p>9</p>
</div>
</div><!-- END gridWrapper -->

Firefox: automatic linebreak with a sibling [float: right] element + overflowing text

I have a problem with Firefox on a really specific graphic implementation.
I think you may understand the problem just by testing this fiddle: on firefox you'll see the problem, on any other browser you'll see the expected result (including IE9).
Design I need:
PNG illustration
I have a main block (dashed border) with a fixed width.
There is 2 lines, one above the other, within the main block. The 2 lines must be align on the right of the main block
Each line contains 2 children. The left ones have a dynamic text (gray background), the right ones are optionnals (blue background). The above right one contains an icon (orange) with a fixed width, the bellow right one is a dynamic temperature (with one decimal maximum).
Blocks are separated by a fixed 5px margin.
Texts and icon must be vertically centered.
In any case, the 2 lines need to have the same width: the smaller one takes the width of the bigger one.
If one line (or both) becomes too large for the main block, the left text (gray background) automatically linebreak.
HTML Code:
<div class="main-wrapper">
<div class="container">
<div class="content upper">
<div class="right-block"><!-- This block is optionnal -->
<div class="icon"></div>
</div>
<div class="left-block">
<div class="vertically-centered">
<p>
Some dynamic text
</p>
</div>
</div>
</div>
<div class="content lower">
<div class="right-block"><!-- This block is optionnal -->
<div class="vertically-centered">
<span>
21,5°
</span>
</div>
</div>
<div class="left-block">
<div class="vertically-centered">
<p>
Some other dynamic text
</p>
</div>
</div>
</div>
</div>
</div>
CSS Code:
/* utilities */
.vertically-centered {
display: table;
height: 100%;
width: 100%;
}
.vertically-centered > * {
display: table-cell;
vertical-align: middle;
}
/* custom styles */
.container {
display: inline-block;
float: right;
max-width: 100%;
}
.content {
width: 100%;
margin: 5px 0px;
height: 85px;
}
.right-block, .left-block {
height: 100%;
}
.right-block {
float: right;
font-size: 42px;
margin-left: 5px;
background-color: lightblue;
}
.left-block {
font-size: 25px;
line-height: 25px;
overflow: hidden;
padding: 0 20px;
text-align: left;
background-color: lightgray;
}
.upper .right-block {
width: 85px;
}
.lower .right-block {
padding: 0 15px;
}
.icon {
position: relative;
top: 20%;
left: 20%;
width: 60%;
height: 60%;
background-color: orange;
}
What I already tried:
Put a display: inline-block on the .left-block div, as suggested here, but it doesn't satisfy the need to have the same width on both lines.
Put a display: inline-block on the .content div; makes the line 100% width on other browsers, and create a big right gap within the .left-block on firefox.
Use white-space: nowrap on the .left-block; didn't help.
Make the .left-block div floating (right or left), but it doesn't work if the text is too large for the main container
And a lot of other things but not a single one compatible with all the browsers (Chrome, Firefox, Safari, IE9+, Edge)...
A precision although I don't think it will change anything: it is responsive.
I'm trying something with flexbox but... IE9... If anybody has a suggestion.
You can use the CSS word-break property to allow line breaks in the middle of long words:
.content {
width: 100%;
margin: 5px 0px;
height: 85px;
word-break: break-all;
}
I found out a solution with flexbox!
I added a display: flex to the .content div with flex-direction: row-reserve to keep the order of the element and still be able to use float: right for IE9.
In addition, there is a flex: auto property on .left-block divs to take as much space as possible (Note: IE11 needs flex-basis to be set to be able to calculate the space wanted by the flex-grow property. That's why I used auto instead of 0 on the flex property. See details)
The completed CSS code
.content {
width: 100%;
margin: 5px 0px;
height: 85px;
display: flex; /* Initialize flexbox */
flex-direction: row-reverse; /* keep the order of the element */
border: 1px dashed gray;
}
.left-block {
font-size: 25px;
line-height: 25px;
overflow: hidden;
padding: 0 20px;
text-align: left;
background-color: lightgray;
flex: auto; /* the text blocks take all the available space */
}
Here's the fiddle with the correction. Sometimes IE9 takes 2 lines of text instead of 1 (the text is 2px larger that the container, I don't know why...) but atleast it's readable!

inline-block scrollbars when browser resized

Here is my css:
.contain
{
min-width: 300px;
background: black;
height: 200px;
display: inline-block;
overflow: auto;
}
.inl1{
/* margin: 5px 5px 5px 5px; */
min-width: 300px;
background: blue;
width: 400px;
height: 200px;
}
<div class=contain>
<div class=inl1></div>
</div>
<div class=contain>
<div class=inl1></div>
</div>
Clearly the two divs display inline, which is what I want.
However, when the browser is resized smaller the divs are displayed one above the other (desired behaviour), but once I make the browser window smaller than min-width, I need to have horizontal scrollbars displayed. This is not happening.
Any help as to why?
Edited: I tried the suggestions here, but they all seem to break the desired behaviour of the divs stacking on top of each other when the browser is sized smaller.
The effect I am after:
display the divs inline (with no scrollbars) in a browser that is wide enough; but in a "narrow" browser (ie mobile) display the divs one on top of another and THEN add horizontal scrolling ONCE the min-width can no longer be displayed for each div.
I think that's a little clearer...
You just need to have a wrapper for the divs and set it with
.wrapper{
min-width: 100%;
white-space: nowrap;
}
Here is the Fiddle: https://jsfiddle.net/1hshzxah/3/
Your outside boxes have the same minimum width as your inside ones, so both will be at least 300px wide, so no scrollbars appear. Because of the defined pixelwidth of your outer elements, your they will not stack next to each other if you do not have 600 pixels to play with or more. If you give your outer boxes a width that can scale (by using % or vw) with the page width, your result magically appears:
.contain {
width: 45%;
background: black;
height: 200px;
display: inline-block;
overflow: auto;
}
.inl1{
/* margin: 5px 5px 5px 5px; */
min-width: 300px;
background: blue;
width: 400px;
height: 200px;
}
#media all and (max-width:600px){
.contain {
width: 100%;
}
}
<div class=contain>
<div class=inl1></div>
</div>
<div class=contain>
<div class=inl1></div>
</div>
(I use 45% because I did not want to bother with floating these nicely next to each other, but you could with some more CSS). You can still add a max-width of 300 pixels to your containers to make sure they don't grow beyond 300px, but still shrink otherwise.

Centering a block that has multiple lines of text

Here is an example I'm working with:
http://jsfiddle.net/adyjzbuh/18/
Here is the code:
<div class="box1">
<div class="box2">Some text</div>
</div>
<div class="box1">
<div class="box2">Some more text, actually, 2 lines of textalicious text</div>
</div>
<div class="box1">
<div class="box3">Some more text, actually, 2 lines of textalicious text</div>
</div>
<div class="box1">
<div class="box4">Some more text, actually, 2 lines of textalicious text</div>
</div>
Here is the CSS:
.box1 {
width: 300px;
border: 1px solid black;
padding: 10px;
text-align: center;
}
.box2 {
display: table;
margin: 0px auto;
border: 1px solid black;
padding: 10px;
text-align: left;
}
.box3 {
display: inline-block;
margin: 0px auto;
border: 1px solid black;
padding: 10px;
text-align: left;
}
.box4 {
display: table-cell;
margin: 0px auto;
border: 1px solid black;
padding: 10px;
text-align: left;
}
As you can see, the first block does exactly what I want. The margins automatically adjust, the block is centered as intended. The issues come when there is multiple lines of text. When I use the same style for the next block with multiple lines of text, the block adjusts the width to 100% of the available space, leaving a big gap on the first line and block not appearing centered.
I tried changing the display to inline-block and table-cell but it does not work (as evidenced by the third and fourth block). I've searched everywhere for solutions and none have worked.
The outer container will always be 300px and the inner block will always have to be flexible and adjust to multi-line text. Any solutions/examples would be greatly appreciated, thank you.
EDIT I forgot to mention the client specifically wants the text to align to the left.
I would add:
text-align: center
or
text-align:justify
instead of:
text-align:left
Is that what you expected to look like?
You might want to put a max-width: 50%; on your innerboxes. The reason is your solution doesn't really work the way you want is your margins are set to auto, so the margin is calculated of the width. So if say your width would be 50% of the parent container (in this case .box1), the margins are automatically calculated to fill up the other 50%, 25% for each side.
Max-width could fix your problem, the innerboxes are still flexible, but only will take up 50% of the width.
.box1 {
width: 300px;
border: 1px solid black;
padding: 10px;
text-align: center;
}
.box2 {
display: table;
margin: 0px auto;
border: 1px solid black;
padding: 10px;
text-align: left;
max-width: 50%;
}
Not sure what you are looking for ultimately, but here is a working example, with using table method, like you have, but using
display:table;
display:table-cell;
accordingly with text aligned in the middle, and centered or left aligned.