Hi everyone, i'm currently working on a note project, i'm trying to center my notes using flex box without any useless spaces, take a look at the photos you will understand what i mean .
bottom space is just fine, the problem is the space that is caused by flex box on the right side , i want the yellow box to resize and fit but stay centered as well, the yellow box is a ul tag and the red boxes are li tags.
here is the css styles : ( container includes the whole page except the header )
.container {
width: 100%;
display: flex;
height: 100vh;
align-items: flex-start;
justify-content: center;
position: relative;
}
ul {
align-content: flex-start;
margin: 40px auto;
max-width: 1400px;
width: fit-content;
height: 80vh;
display: flex;
justify-content: flex-start;
align-items: flex-start;
flex-wrap: wrap;
overflow-y: scroll;
margin-top: 100px;
border: 3px solid yellow;
}
ul li {
border: 2px solid red;
list-style-type: none;
font-size: 20px;
margin: 5px;
background: linear-gradient(rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5));
backdrop-filter: blur(10px);
width: 330px;
height: 200px;
display: flex;
overflow: hidden;
justify-content: space-between;
align-items: flex-start;
flex-direction: column;
padding: 20px;
border-radius: 5px;
position: relative;
transition: height 0.3s;
}
here is the HTML codes : ( sorry it's not clean )
<title>Dashboard</title>
<div class="container">
<ul>
<li class="item">
<div class="priority"></div><span class="title c-title"> title </span>
<span class="content c-content"> Content </span>
<span class="date"> date </span>
<div class="item_buttons">
<button class="detail faint_color"><img class="edit-icon" src="/icons/invisible.svg" alt="see icon"></button></button>
<button class="detail faint_color"><img class="edit-icon" src="/icons/edit.svg" alt="edit icon"></button></button>
<button class="deleteButton detail faint_color"><img class="edit-icon" src="/icons/trash.svg" alt="delete icon"></button>
</div>
</li>
</ul>
</div>
<div class="addButton">
<img class="addButtonImage" src="/add.svg" alt="add new note" />
<div class="smallMenu hide">
<a href="/modify/folders">
<button class="folders_button"><img src="/icons/folder.svg" alt="folder icon"></button>
</a>
<a href="/note/add">
<button class="addNote_button"><img src="/icons/pen.svg" alt="pen icon"></button>
</a>
</div>
</div>
There's a number of solutions for this one, depending which way you want to go,
If the notes don't have to be exactly 330px wide, you can achieve removing the gaps by replacing:
width: 330px;
with
flex: 200px;
This takes advantage of the fluid responsiveness of flexbox.
One issue with this flex solution is the 'leftover' element upon wrapping: e.g. with three elements across, the fourth will wrap and grow to the full width of the parent:
To get around this with flex, you would need to either:
change flex to something like flex: 0 1 50%; with percentage values and flex-grow disabled, which means you would need #media queries to give the lists the fluidity they had before
use a JavaScript solution to dynamically set the width of the last element based on the other lists (like #SnoopFrog's answer)
If you do need the notes to be 330px wide, I would set the parent <ul> to have a set size twice that of the lists width: 785px; and ensure that justify-content: center;
Alternatively, turning to CSS grid or a simple inline-block method may fit your needs but both would need #media queries for responsivity.
As I said in the comment, I don't think you can solve this using pure HTML/CSS, but you could calculate how many elements can fit at given time inside your .container and change width of your ul.
Check this code below:
function totalWidth(element) {
style = window.getComputedStyle(element)
return parseFloat(style.marginLeft) + parseFloat(style.marginLeft) + parseFloat(style.width)
}
function resizeContainer() {
const container = document.querySelector(".container")
const element = document.querySelector(".container ul")
const children = document.querySelector(".container ul li")
const childrenWidth = totalWidth(children)
const amountFits = Math.floor(Math.min(container.offsetWidth, 1400) / childrenWidth)
element.style.width = `${childrenWidth * amountFits}px`
}
resizeContainer()
window.addEventListener("resize", resizeContainer)
.container {
width: 100%;
display: flex;
height: 100vh;
align-items: flex-start;
justify-content: center;
position: relative;
}
ul {
align-content: flex-start;
margin: 40px auto;
max-width: 1400px;
width: fit-content;
height: 80vh;
display: flex;
justify-content: flex-start;
align-items: flex-start;
flex-wrap: wrap;
overflow-y: scroll;
margin-top: 100px;
border: 3px solid yellow;
padding: 0;
}
ul li {
border: 2px solid red;
list-style-type: none;
font-size: 20px;
margin: 5px;
background: linear-gradient(rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5));
backdrop-filter: blur(10px);
width: 330px;
height: 200px;
display: flex;
overflow: hidden;
justify-content: space-between;
align-items: flex-start;
flex-direction: column;
padding: 20px;
border-radius: 5px;
position: relative;
transition: height 0.3s;
box-sizing: border-box;
}
<div class="container">
<ul>
<li>test</li><li>test</li>
<li>test</li><li>test</li>
</ul>
</div>
Mind the fact that I added box-sizing: border-box; to your ul li so it's a bit easier to calculate the actual size of the element. Naturally you could ignore this and change my totalWidth method to calculate it the way you'd like.
I don't think you can do it differently but I'd like to be proven wrong.
* {
/* just for reset and for remove all margins and paddings */
box-sizing: border-box;
margin: 0;
padding: 0;
}
ul {
display: flex;
/*justify-content: flex-start; don't need this, is start by default
align-items: flex-start;*/
/* magical words that they can align internal box(li) */
justify-content: center;
align-items: center;
margin: 40px auto; /*auto <--> both part is ok*/
max-width: 1400px;
/* just for see the center(you can remove this width static of 25rem */
width: 25rem; /* width: fit-content; */
height: 80vh;
overflow-y: scroll;
margin-top: 100px;
border: 3px solid yellow;
}
ul li {
display: flex;
justify-content: space-between;
align-items: flex-start;
flex-direction: column;
border: 2px solid red;
list-style-type: none;
background: linear-gradient(rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5));
backdrop-filter: blur(10px);
width: min(100%, 330px); /*make it responsive, when shrink down, under 330px, is take 100% of width avaiable, and not overflowing*/
height: 200px;
margin: 10px auto; /*in every elements, you can use margin auto for both parts*/
padding: 20px;
border-radius: 5px;
transition: all 0.3s; /*transition:height 0.3 --> not height, but all inside!*/
/* overflow: hidden; don't need, that not should be overflow */
/* position: relative; Is by default! like height:auto*/
}
/* if you want to style your buttons, write this code all times */
/* remove deafult aspect of a btn and others, beacuse every browser take a different style*/
button, input, a {
appearance: none;
-webkit-appearance: none;
-moz-appearance: none;
}
<title>Dashboard</title>
<ul>
<div class="wrapper">
<li class="item">
<div class="priority"></div>
<span class="title c-title"> title </span>
<span class="content c-content"> Content </span>
<span class="date"> date </span>
<div class="item_buttons">
<a href="">
<button class="detail faint_color">
<img class="edit-icon" src="/icons/invisible.svg" alt="see icon">
</button>
</a>
<a href="">
<button class="detail faint_color">
<img class="edit-icon" src="/icons/edit.svg" alt="edit icon">
</button>
</a>
<a href="">
<button class="deleteButton detail faint_color">
<img class="edit-icon" src="/icons/trash.svg" alt="delete icon">
</button>
</a>
</div>
</li>
</div>
</ul>
<div class="addButton">
<img class="addButtonImage" src="/add.svg" alt="add new note" />
<div class="smallMenu hide">
<a href="/modify/folders">
<button class="folders_button">
<img src="/icons/folder.svg" alt="folder icon">
</button>
</a>
<a href="/note/add">
<button class="addNote_button">
<img src="/icons/pen.svg" alt="pen icon">
</button>
</a>
</div>
</div>
I'm constructing a simple layout with a title and sub-title. When the two can be displayed on one line without the text wrapping, they should do so with a small amount of spacing between them. In all other cases, the title and sub-title should occupy 100% width. There should be no margin-left on the sub title.
I have created this using Flexbox and the gap property. It renders properly in Firefox:
Here's the code:
header {
font-family: sans-serif;
background-color: rebeccapurple;
color: #fff;
padding: 0 5px;
}
.container {
max-width: 800px;
width: 100%;
flex-grow: 1;
margin-left: auto;
margin-right: auto;
}
header .container {
display: flex;
flex-wrap: wrap;
flex-direction: row;
gap: 0.5rem;
align-items: baseline;
}
<header>
<div class="container">
<h1>Long title for the page itself</h1>
<h2>Subtitle</h2>
</div>
</header>
<br />
<header>
<div class="container">
<h1>Shorter title</h1>
<h2>Subtitle</h2>
</div>
</header>
Unfortunately, popular browsers such as Google Chrome have failed to implement support for gap used in conjunction with a display: flex layout.
Is there a way I can implement this using e.g. display: inline-block elements and negative margins such that it will work in legacy browsers like Chrome and Internet Explorer?
Instead of gap: .5rem, use margin-right: .5rem on the h1.
h1 {
margin-right: .5rem;
}
.container {
max-width: 800px;
margin-left: auto;
margin-right: auto;
display: flex;
flex-wrap: wrap;
align-items: baseline;
}
header {
font-family: sans-serif;
background-color: rebeccapurple;
color: #fff;
padding: 0 5px;
}
<header>
<div class="container">
<h1>Long title for the page itself</h1>
<h2>Subtitle</h2>
</div>
</header>
<br />
<header>
<div class="container">
<h1>Shorter title</h1>
<h2>Subtitle</h2>
</div>
</header>
Pen here.
HTML
<header>
<div id="logo-div">
MyLogo
</div>
<nav>
<ul class="nav-list">
<li class="item">LINK #1</li>
<li class="item">LINK #2</li>
<li class="item">LINK #3</li>
<li class="item">LINK #4</li>
<li class="item">LINK #5</li>
</ul>
</nav>
</header>
CSS
header{
display: inline-block;
width: 90%;
}
#logo-div{
margin-right: 50px;
float: left;
font-size: 28px;
color: red;
font-weight: 800;
line-height: 60px;
}
nav{
float: right;
}
.nav-list{
display: flex;
height: 150px;
width: auto;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-evenly;
align-items: flex-start;
align-content: flex-start;
margin: 0%;
padding: 0%;
width: auto;
list-style-type: none;
}
.item{
background-color: #d6315d;
height: 50px;
width: 150px;
margin: 5px;
text-align: center;
line-height: 45px;
font-weight: 600;
}
Typical website header with inline-block display, logo div on left and navbar on right.
I need to have flex-wrapping navbar to accommodate various device widths, at least until screen-width = 600px where it can be changed to a hamburger. So I make the nav-list height 3 times the height of the list item.
Problem is that if I float the nav block to the right within the header, the nav item-list will only wrap UNDER the logo-div, not beside it.
I can solve this by removing the float from the nav block altogether. But now the nav block drifts to the left on zoom, so the whole page looks off-center.
Anyone got any ideas ?
EDIT
This CodePen achieves the desired effect of stacking nav items on rows within a navbar without the navbar spilling below the logo - at least till screen widths go below ~ 400px.
If I understand correctly you are having an issue with the items not being aligned when the screen is smaller. The best way to do this is using display: flex to get alignment done easily. I have done a sample code and hope it helps your problem (align-items-center aligns all items including your logo to the center in the row when the screen size changes. If you don't need it you can remove it)
HTML
<header>
<div class="d-flex flex-row align-items-center">
<div class="logo">
MyLogo
</div>
<nav>
<ul class="nav-list">
<li class="item">LINK #1</li>
<li class="item">LINK #2</li>
<li class="item">LINK #3</li>
<li class="item">LINK #4</li>
<li class="item">LINK #5</li>
</ul>
</nav>
</div>
</header>
CSS
.nav-list {
display: flex;
width: auto;
flex-direction: row;
flex-wrap: wrap;
justify-content: flex-start;
align-items: flex-start;
align-content: flex-start;
margin: 0%;
padding: 0%;
list-style-type: none;
}
.item {
background-color: #d6315d;
height: 50px;
width: 150px;
margin: 5px;
text-align: center;
line-height: 45px;
font-weight: 600;
}
.d-flex {
display: flex;
}
.flex-row {
flex-direction: row;
}
.align-items-center {
align-items: center;
}
.logo {
margin-right: 50px;
font-size: 28px;
color: red;
font-weight: 800;
}
JS Fiddle Link: https://jsfiddle.net/SJ_KIllshot/7u36m194/
I would like in CSS force break-line on space and not break words like "Plan[break-line]individual"
I'm using Flexbox to make an easy responsive code.
HTML
<section class="card-container">
<div class="card card-inline text-center">
<div class="card-block">
<h4 class="card-title">Plan individual</h4>
<p class="card-text">€10.00 / year</p>
<button click="#'">Sign in</button>
</div>
</div>
...
</section>
style.css
.card-container{
display: flex;
height: inherit;
width: inherit;
}
.card{
position: relative;
display: flex;
flex-direction: column;
min-width: 0;
background-color: #fff;
background-clip: border-box;
border: 1px solid rgba(0,0,0,.125);
border-radius: .25rem;
width: 170px;
}
.card-inline{
display: inline-flex;
margin: .75rem;
}
.card-block {
flex: 1 1 auto;
padding: 1.25rem;
display: flex;
flex-direction: column;
justify-content: space-between;
}
h4.card-title{
margin: .5rem !important;
font-size: 100% !important;
}
.text-center{
text-align: center !important;
}
I tried white-space, word-wrap, flex-wrap... without success.
Does anyone have an idea how to prevent the words from being hyphenated?
The code you included doesn't give the result you show in your image, so you must have a CSS rule somewhere else that's causing it.
However, you should be able to override it with the following:
h4 {
hyphens: none;
}
For a simpler solution, just at a <br/> tag to your html in between the words. You can add a class if you want to target it with media queries to turn the break on and off based on the screen width.
The following code works in all modern browsers that I've tested (safari, chrome and firefox) except internet explorer. I'm trying to vertically and horizontally center an image inside logo. The problem is that the img overflows the container which is 50px 50px. If I remove flexbox from the css, the image does not overflow, but then it is no longer centered.
I've had a look at Flexbugs to try and solve the issue. But no luck. Any suggestion is much appreciated.
html
<div class="content">
<ul>
<li>
<section class="post">
<div class="post-header">
<div class="logo">
<img src="#" alt="">
</div>
</div>
</section>
</li>
</ul>
</div>
css
.content {
max-width: 400px;
padding-left: 1em;
padding-right: 1em;
}
.logo {
-webkit-box-align: center;
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
border: 1px solid #000;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
float: left;
height: 50px;
width: 50px;
}
img {
max-height: 100%;
max-width: 100%;
}