How do I equally place multiple divs on multiple rows? - css

I'd like to place divs equally spaced on multiple rows. I've tried setting margins or justify-content but none of them worked so far. I want the course-lists in each row to be equally spaced but the space between the lists depends on the length of the name of the courses when I tried setting margins. I'm new to CSS so I'm sorry if the question or my codes are confusing.
HTML
<div className="course-section">
<div>
<h2 id="course-tag">Coursework</h2>
</div>
<div className="course-box">
<div className="course-list-row">
<div className="course-bullet"></div>
<div className="course-list">Data Structures</div>
<div className="course-bullet"></div>
<div className="course-list">Computer Architecture</div>
</div>
<div className="course-list-row">
<div className="course-bullet"></div>
<div className="course-list">Numerical Analysis</div>
<div className="course-bullet"></div>
<div className="course-list">Numerical Methods</div>
</div>
<div className="course-list-row">
<div className="course-bullet"></div>
<div className="course-list">Discrete Structures</div>
<div className="course-bullet"></div>
<div className="course-list">Intro to Computer Science</div>
</div>
<div className="course-list-row">
<div className="course-bullet"></div>
<div className="course-list">Applied Linear Algebra</div>
<div className="course-bullet"></div>
<div className="course-list">Physics Courses</div>
</div>
</div>
</div>
CSS
#mixin bullet {
height: 15px;
width: 15px;
background-color: blue;
display: inline-block;
}
#mixin resume-box {
background-color: white;
height: 350px;
width: 700px;
margin: auto;
overflow: hidden;
-webkit-box-shadow: 0 0 15px 3px #b0abaa;
-moz-box-shadow: 0 0 15px 3px #b0abaa;
box-shadow: 0 0 15px 3px #b0abaa;
}
.course-section {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
#course-tag {
margin-bottom: 40px;
margin-right: 530px;
font-weight: bold;
font-size: 30px;
}
.course-box {
#include resume-box;
margin-bottom: 80px;
padding: 40px 50px 40px 50px;
}
.course-bullet {
#include bullet;
}
.course-list {
display: inline-block;
margin-left: 10px;
font-size: 20px;
}
.course-list-row {
margin-bottom: 20px;
}
}
It's what I want.

Well I think it can be simplyfied like this:
HTML:
<div class="course-section">
<div>
<h2 id="course-tag">Coursework</h2>
</div>
<div class="course-box">
<div class="course-list">Data Structures</div>
<div class="course-list">Computer Architecture</div>
<div class="course-list">Numerical Analysis</div>
<div class="course-list">Numerical Methods</div>
<div class="course-list">Applied Linear Algebra and lorem ipsum dolor sit amet</div>
<div class="course-list">Discrete Structures</div>
<div class="course-list">Intro to Computer Science</div>
<div class="course-list">Physics Courses</div>
</div>
</div>
scss:
#mixin bullet {
height: 15px;
width: 15px;
background-color: blue;
display: inline-block;
}
#mixin resume-box {
background-color: white;
height: 350px;
width: 700px;
margin: auto;
overflow: hidden;
box-shadow: 0 0 15px 3px #b0abaa;
}
* {
box-sizing: border-box;
}
.course-section {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
#course-tag {
margin-bottom: 40px;
margin-right: 530px;
font-weight: bold;
font-size: 30px;
}
.course-box {
#include resume-box;
display: flex;
flex-wrap: wrap;
padding: 40px 50px 40px 50px;
.course-list {
flex: 0 0 50%;
position: relative;
font-size: 20px;
padding-left: 35px;
&:before {
content: '';
position: absolute;
left: 10px;
top: 3px;
#include bullet;
}
}
}
}
The important things here are:
* {
box-sizing: border-box;
}
Flex does not really need this, but i usually use this box-sizing so margins and paddings won't get sum to dom elements total height and/or width. I find border-box to be more precise.
.course-box {
display: flex;
flex-wrap: wrap;
}
The container is set to flex so we can use the flex property of its child elements to have them aligned and distributed. flex-wrap: wrap basically does what it says, force content inside a flex container to wrap when width is reached. (try to put it as nowrap in the snippet and see what happens)
.course-list {
flex: 0 0 50%;
}
Finally, we set the flex property of the list elements to 0 0 50%, this basically translates into 0 (this element can't be shrinked) 0 (this element can't be expanded) 50% (width of the element). So if you would like to have 3 elements per row it would be 0 0 33% and so.
You could even make it responsive. For example:
.course-list {
flex: 0 0 50%;
#media only screen and (max-width: 767px) {
flex: 0 0 100%;
}
}
this would result into two column rows in desktop and one column rows in mobile.
Also, avoid use a div to fake a bullet, better use the :after or :before pseudo elements as the snippet below, it will result in much cleaner html.
Here is a snippet:
* {
box-sizing: border-box;
}
.course-section {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.course-section #course-tag {
margin-bottom: 40px;
margin-right: 530px;
font-weight: bold;
font-size: 30px;
}
.course-section .course-box {
background-color: white;
height: 350px;
width: 700px;
margin: auto;
overflow: hidden;
box-shadow: 0 0 15px 3px #b0abaa;
display: flex;
flex-wrap: wrap;
padding: 40px 50px 40px 50px;
}
.course-section .course-box .course-list {
flex: 0 0 50%;
position: relative;
font-size: 20px;
padding-left: 35px;
}
.course-section .course-box .course-list:before {
content: "";
position: absolute;
left: 10px;
top: 3px;
height: 15px;
width: 15px;
background-color: blue;
display: inline-block;
}
<div class="course-section">
<div>
<h2 id="course-tag">Coursework</h2>
</div>
<div class="course-box">
<div class="course-list">Data Structures</div>
<div class="course-list">Computer Architecture</div>
<div class="course-list">Numerical Analysis</div>
<div class="course-list">Numerical Methods</div>
<div class="course-list">Applied Linear Algebra and lorem ipsum dolor sit amet</div>
<div class="course-list">Discrete Structures</div>
<div class="course-list">Intro to Computer Science</div>
<div class="course-list">Physics Courses</div>
</div>
</div>

Related

CSS - Inner div not taking available height

Having a bit of a mare with this but it should be so simple, I need my .qualification-delete-container div to take 100% of the parent div.
I've attached a fiddle so you can see. If you reduce the screen size, when the content of the .qualification-row-details div (the turquoise one) takes up 2 lines then the .qualification-delete-container (yellow one) needs to respond and take the new height of the parent.
Both of the child div's are display:inline-block
.qualification-row {
width: 100%;
padding: 10px 0px 10px 0px;
text-align: left;
background-color:green;
}
.qualification-row-details {
width: calc(100% - 60px);
height: 100%;
display: inline-block;
background-color: turquoise;
}
.qualification-delete-container {
display: inline-block;
width: 55px;
vertical-align: top;
min-height: 100%;
float: unset;
background-color: yellow;
}
.flex-vertical-center {
display: flex;
flex-direction: column;
justify-content: center;
height: 100%;
}
<br/>
<div class="qualification-row js-qualification-row">
<div class="qualification-row-details">
degree type, classification, Course title, year, awarding instition
</div>
<div class="qualification-delete-container">
<div class="flex-vertical-center">
<a class="qualification-delete">delete</a>
</div>
</div>
</div>
Change your qualification-row css to -
.qualification-row {
display : flex; // ADD DISPLAY FLEX
width: 100%;
padding: 10px 0px 10px 0px;
text-align: left;
background-color:green;
}
You can do it by using display table. I have solved it by using display table and table cell. please have a look .
I've attached a fiddle so you can see.
.qualification-row {
width: 100%;
text-align: left;
background-color:green;
display: table;
}
.qualification-row-details {
width: calc(100% - 60px);
height: 100%;
display: table-cell;
}
.qualification-delete-container {
display: table-cell;
width: 55px;
vertical-align: middle;
min-height: 100%;
float: unset;
background-color: yellow;
text-align: center;
}
.qualification-row-details-text {
margin: 10px 10px 10px 0;
background-color: turquoise;
}
<br/>
<div class="qualification-row js-qualification-row">
<div class="qualification-row-details">
<div class="qualification-row-details-text">
degree type, classification, Course title, year, awarding instition
</div>
</div>
<div class="qualification-delete-container">
<a class="qualification-delete">delete</a>
</div>
</div>

Adding a link to an entire flexbox

I can't figure out how to make an entire flexbox a link without the content messing up somehow. It gets complicated for me because I have an image at the top of each box.
My flexboxes are set up as:
.cards {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.card {
flex: 0 1 100%;
margin: 0 10px 10px 0;
border: 1px solid grey;
box-shadow: 1px 1px 3px #888;
}
.card-content {
padding: 10px;
}
.card-content p {
line-height: 120%;
}
.card-header {
position: relative;
height: 200px;
overflow: hidden;
background-repeat: no-repeat;
background-size: cover !important;
background-position: center;
margin: 0;
padding: 0;
background-color: #000;
}
And some media queries:
#media all and (min-width: 50em) {
.card {flex: 0 1 30%;}
.card-content p {font-size: .9em;}
.card-content a {font-size: .9em;}
}
And the HTML structure of each box/card:
<div class="cards">
<div class="card">
<div class="card-header" style="background-image: url(https://)"></div>
<div class="card-content">
<h3>Header</h3>
<p>Description.</p>
</div>
</div>
Again, no matter where I put an A tag, it'll majorly mess up the formatting.
How to make an entire flexbox a link
Don't use a div with a class of .card as a wrapper use a link instead with the same class, everything else is the same.
The whole card is now a link!
<a href="#" class="card">
<div class="card-header" style="background-image: url(https://)"></div>
<div class="card-content">
<h3>Header</h3>
<p>Description.</p>
</div>
</a>

flexbox how to achieve this specific layout?

Like in the image - http://i65.tinypic.com/aa7ndw.png Examples and live flex configurators are explain only simple examples, or I just don't get it.
Will I be able to use media queries to for example not display a4 when < 800px?
I have always used float and flex is somehow 'different' anyway I would like to know it better, so any help is appreciated.
flex specific example
Apply display: flex to a container and its child elements will be displayed in flex. For this layout, you will want to wrap the elements when width is already filled for the current row.
The header and footer will be width: 100%, taking a full row. #a3 and #a4 will have flex: 1 to distribute the width of their row, taking each one 50% of the width.
div.flex-container{
width: 200px;
height: 300px;
background-color: black;
display: flex;
flex-flow: row wrap;
}
#a1, #a2{
width: 100%;
}
#a3, #a4{
flex: 1;
}
#a5, #a6, #a7{
height: 50px;
width: 80%;
margin: auto;
margin-bottom: 1rem;
}
/* Example styles */
div{
text-align: center;
}
#a1{
background-color: red;
}
#a2{
background-color: limegreen;
}
#a3{
background-color: royalblue;
}
#a4{
background-color: cyan;
}
#a5, #a6, #a7{
background-color: fuchsia;
}
<div class="flex-container">
<div id="a1">a1</div>
<div id="a3">a3</div>
<div id="a4">a4
<div id="a5">a5</div>
<div id="a6">a6</div>
<div id="a7">a7</div>
</div>
<div id="a2">a2</div>
</div>
And yeah, you can use media queries as normal
div.flex-container{
width: 200px;
height: 300px;
background-color: black;
display: flex;
flex-flow: row wrap;
}
#a1, #a2{
width: 100%;
}
#a3, #a4{
flex: 1;
}
#a5, #a6, #a7{
height: 50px;
width: 80%;
margin: auto;
margin-bottom: 1rem;
}
#media (max-width: 800px){
#a4{
display: none;
}
}
/* Example styles */
div{
text-align: center;
}
#a1{
background-color: red;
}
#a2{
background-color: limegreen;
}
#a3{
background-color: royalblue;
}
#a4{
background-color: cyan;
}
#a5, #a6, #a7{
background-color: fuchsia;
}
<div class="flex-container">
<div id="a1">a1</div>
<div id="a3">a3</div>
<div id="a4">a4
<div id="a5">a5</div>
<div id="a6">a6</div>
<div id="a7">a7</div>
</div>
<div id="a2">a2</div>
</div>

CSS Flexbox - Same height when a column contains multiple parts?

I have a simple question. I have a basic flex-box layout. One column takes up 2/3 of the layout, the other takes up a third. Both of them have a purple semi-transparent header (.85) with their contents are in an opaque black box.
http://codepen.io/StuffieStephie/pen/XdoBqL
body {
background: url('http://www.amazingwallpaperz.com/wp-content/uploads/Black-and-Purple-Abstract-Cool-Backgrounds-Wallpaper.jpg') center center;
background-size: cover;
font-family: 'Open Sans';
}
#featuredSlide, #featuredSlide img {
width: 100%;
max-width: 800px;
margin: 0 auto;
}
.container {
display: -webkit-flex;
display: flex;
justify-content: space-between;
color: #fff;
}
.sect {
box-sizing: border-box;
width: 32%;
-webkit-flex: 1;
flex: 1;
margin: 30px; text-align: center;
}
.sect + .sect {
margin-left: 10px;
}
.sect.feat {width: 65%;
-webkit-flex: 2;
flex: 2;
}
.sect .cont {
background:#414141;
padding-top: 40px;
padding-bottom: 30px;
border-radius: 0 0 5px 5px;
}
.sect h2 {
background:#414141;
background-color: rgba(52,41,109,.85);
margin-bottom: 0;
text-align: center;
text-transform: uppercase;
font-size: 2em;
font-weight: 300;
padding: 30px 10px;
border-radius: 5px 5px 0 0;
}
<head><link href='http://fonts.googleapis.com/css?family=Open+Sans:300,400,600' rel='stylesheet' type='text/css'>
</head>
<body>
<div class="container">
<div class="sect feat">
<h2> Featured Guests & Programming</h2>
<div class="cont">
<!-- SLIDE SHOW -->
<div id="featuredSlide" class="owl-carousel">
<img src="http://placehold.it/800x300/5d64a8">
</div> <!-- CLOSING SLIDE SHOW DIV TAG --></div>
</div>
<div class="sect">
<h2> News </h2>
<div class="cont">Some thrilling article</div>
</div>
</div>
<div class="clearfix"></div>
</body>
Both .sect elements are the same height. I want both .sect .cont elements to be the same height. I know I can make them look the same height by setting a background-color to .sect but that will ruin the transparency of my headers.
Any thoughts?
You can add flex-direction: column; to your .sect class, and give your .cont class a flex-grow: 1. This will make the .cont div's take up the remaining height of the .sect class.
.sect {
display: flex;
flex-direction: column;
}
.cont {
flex-grow: 1;
}
CodePen
You absolutely can do this with css only. Add the following to your .sect properties:
overflow: hidden;
position: relative;
border-radius:5px;
and add this to make the heights match:
.sect + .sect .cont::after {
background: #414141 none repeat scroll 0 0;
content: "";
height: 3000px;
left: 0;
position: absolute;
width: 100%;
}
You should also then be able to take out your border radii from the h2 and .cont as well.

Can it flexbox? Chat window with input at the bottom, chats scrolling up

Seems like it should be possible with flexbox, but I can't figure it out.
http://codepen.io/MichaelJCole/pen/NGBVGe
Goals:
textarea (for typeing in messages) stays at the bottom the whole time.
chats start at the bottom, then scroll up as needed.
If you use the "Google Hangouts", like the message app in that.
Here's the markup:
<div id="chatBar">
<div id="chatList">
<div class="chat mine">hello world</div>
<div class="chat theirs">hello moon</div>
</div>
<input id="chatBarInput" class="form-control" type="textarea">
</div>
And here's the CSS:
html, body { height: 100%; }
#chatBar {
height: 100%;
display: flex;
flex-flow: column nowrap;
justify-content: flex-end;
overflow: none;
}
#chatList {
flex: 0 1 auto;
display: flex;
flex-flow: column nowrap;
justify-content: flex-end;
overflow-y: scroll;
}
#chatBarInput {
flex: 1 0 auto;
}
.chat {
flex: none;
align-self: flex-start;
background-color: lightgreen;
}
.chat.mine {
align-self: flex-end;
background-color: pink;
}
I can't get #chatBar to "squeeze" #chatList without setting a height. Which is what I was trying to avoid by using flexbox :-/
Sorry, I'm a backend coder. Tried a bunch of stuff, then pared it down for the CodePen.
Seems like I should be able to tell the inner flexbox to scroll, while leaving the outer alone. Do I have to use position:absolute?
I can't get #chatBar to "squeeze" #chatList without setting a height.
Which is what I was trying to avoid by using flexbox
You had the flex-basis set to auto for all elements. Without explicit height, the flex model will automatically try to accommodate everything inside the available space by shrinking or expanding the elements. This is why you are unable to get the #chatList to work as intended. The div itself as well as the individual chats all expand or shrink within the available space.
What you should do is to start simple:
#chatBar {
height: 100%; overflow: hidden;
display: flex; flex-flow: column;
}
#chatList {
/* grow or shrink as required from flex-basis height of 20% */
flex: 1 1 20%;
display: flex; flex-direction: column;
overflow: auto;
}
/* do not grow or shrink with a flex-basis height of 80% */
#chatBarInput { flex: 0 0 80%; }
And you will be able to see it working. You could then take it further from here.
Your modified codepen: http://codepen.io/Abhitalks/pen/ZbjNvQ/
Goals:
textarea (for typeing in messages) stays at the bottom the whole time.
chats start at the bottom, then scroll up as needed.
If you use the "Google Hangouts", like the message app in that.
The trick would be to use flex-direction: column-reverse and prepend the new messages to the container instead of appending those.
I took an old answer of mine and changed the layout to flex-model for a demo of this purpose. You can peruse the code to see how it's done.
Demo Fiddle: http://jsfiddle.net/abhitalks/khj4903t/
Demo Snippet:
var btn = document.getElementById('btn'),
inp = document.getElementById('inp'),
chats = document.getElementById('chatWindow')
;
btn.addEventListener('click', postMsg);
inp.addEventListener('keyup', function(e) {
if (e.keyCode == 13) { postMsg(); }
});
function postMsg() {
var msg = inp.value,
bubble = document.createElement('div'),
p = document.createElement('p');
if (msg.trim().length <= 0) { return; }
bubble.classList.add('bubble');
bubble.classList.add('right');
p.textContent = msg;
bubble.appendChild(p);
inp.value = '';
chats.insertBefore(bubble, chats.firstChild);
}
* { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; overflow: hidden; }
.wrap {
margin: 8px; height: 90%; width: 50%;
display: flex; flex-direction: column;
}
.container {
flex: 1 1 90%; display: flex; flex-direction: column;
background-color: #eee; border: 1px solid #ccc; overflow: auto;
}
.form { flex: 0 0 32px; display: flex; border: 1px solid #ddd; }
.form > input[type=text] { flex: 1 1 auto; border: 1px solid #eee; }
.form > input[type=button] { flex: 0 0 20%; border: 1px solid #eee; }
.bubble { flex: 1 1 auto; clear: both; } /* clear the floats here on parent */
.bubble p {
border-radius: 5px;
padding: 8px; margin: 8px 12px;
max-width: 80%; /* this will make it not exceed 80% and then wrap */
position: relative; transition: background-color 0.5s;
}
.left p { background-color: #ccc; float: left; } /* floated left */
.right p { background-color: #33c; color: #fff; float: right; } /* floated right */
/* classes below are only for arrows, not relevant */
.left p::before {
content: ''; position: absolute;
width: 0; height: 0; left: -8px; top: 8px;
border-top: 4px solid transparent;
border-right: 8px solid #ccc;
border-bottom: 4px solid transparent;
}
.right p::after {
content: ''; position: absolute;
width: 0; height: 0; right: -8px; bottom: 8px;
border-top: 4px solid transparent;
border-left: 8px solid #33c;
border-bottom: 4px solid transparent;
}
<div class="wrap">
<div id="chatWindow" class="container">
<div class="bubble left"><p>msg</p></div>
<div class="bubble left"><p>long message</p></div>
<div class="bubble right"><p>ultra long message which can wrap at eighty percent </p></div>
<div class="bubble left"><p>lorem ipsum</p></div>
<div class="bubble right"><p>very long message</p></div>
<div class="bubble right"><p>one more message</p></div>
<div class="bubble left"><p>lorem ipsum</p></div>
<div class="bubble right"><p>another message</p></div>
<div class="bubble left"><p>lorem ipsum</p></div>
<div class="bubble right"><p>yet another message</p></div>
<div class="bubble left"><p>lorem ipsum</p></div>
</div>
<div id="inputWindow" class="form">
<input id="inp" type="text" />
<input id="btn" type="button" value="Send" />
</div>
</div>
The vertical scrollbar on the browser exists because you've set a height: 100% to the body, and the user agent stylesheet applies a default margin to the body, typically 8px all around. So, 100% + 16px launches the vertical scroll.
Add this to your CSS: body { margin: 0; }
To apply the scrollbar to the inner flexbox (.chatlist), here are two adjustments:
#chatList {
flex: 0 1 75px; /* specify a height */
display: flex;
flex-flow: column nowrap;
/* justify-content: flex-end; REMOVE */
overflow-y: scroll;
}
DEMO: http://jsfiddle.net/5p2vy31p/1/

Resources