I have problem with flex-wrap. When I set it and set width of child to 100% (to take entire "line"), it dont shrink.
Look at my code:
https://codepen.io/dinoq-the-reactor/pen/OJRJoNm
HTML:
<div id="main-container">
<div id="sub-container">
<div class="flex-container">
<div id="i1" class="flex-item">Icon</div>
<div id="i2" class="flex-item">some text, flex it!</div>
<div id="i3" class="flex-item">Icon</div>
<div id="i4" class="flex-item">Text on new line</div>
</div>
<div>
</div>
CSS:
#main-container{
width: auto;
position: absolute;
z-index: 9900;
}
#sub-container{
width:100%;
}
.flex-container {
background-color:blue;
display: flex;
flex-wrap: wrap;
}
.flex-item {
border: solid 1px green;
border-collapse: collapse;
background: grey;
color: white;
font-size: 3em;
}
#i2{
flex: 1;
}
#i4{
flex: 0 0 100%;
}
What I want is to achieve something like this:
Instead I got this:
Note: I really need use "flex-wrap" and html structure which I have... It is part of bigger project, and I can edit only CSS...
Note2: My container is so expanded because width of it is width of all child elements, so it counts width of my 4. child (which is on new line). This is some source of problem, but how it solve?
Thanks!
Below is the solution for your problem.
#main-container {
width: auto;
position: absolute;
z-index: 9900;
}
#sub-container {
width: 100%;
}
.flex-container {
background-color: gray;
font-size: 0;
}
.flex-item {
border: solid 1px green;
border-collapse: collapse;
color: white;
font-size: 3em;
display: inline-block;
font-size: 3rem;
}
.flex-item:last-child {
display: block;
}
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8" />
<meta content="width=device-width, initial-scale=1.0" name="viewport" />
<link rel="stylesheet" href="./style.css" />
</head>
<body>
<div id="main-container">
<div id="sub-container">
<div class="flex-container">
<div id="i1" class="flex-item">Icon</div>
<div id="i2" class="flex-item">some text, flex it!</div>
<div id="i3" class="flex-item">Icon</div>
<div id="i4" class="flex-item">People of this world are travellers</div>
</div>
<div>
</div>
</body>
</html>
Related
In the middle (not banner or footer) section of my page, I have two elements: classed as left-container and right-container.
I want to fill the left-container with many columns of a specific width, and have them overflow to the left, such that the page loads to show their right-most element and the user must scroll left to see the others.
How is this possible with flexbox?
Here's my code:
#import url("https://fonts.googleapis.com/css2?family=Heebo:wght#600&display=swap");
body {
margin: 0;
padding: 0;
}
.page-container {
display: flex;
flex-direction: column;
height: 100vh;
background-color: teal;
align-items: stretch;
flex-direction: column;
}
.banner {
background-color: lightcyan;
position: relative;
width: 100%;
height: 80px;
}
.banner-title {
font-family: "Heebo";
font-weight: 600;
font-size: 40px;
padding: 10px;
}
.footer {
width: 100%;
background-color: thistle;
height: 30px;
}
.body-container {
background-color: lightcyan;
width: 100vw;
height: 100vh;
display: flex;
justify-content: flex-end;
}
.left-container {
background-color: greenyellow;
width: 100vw;
display: flex;
justify-content: flex-end;
flex-wrap: nowrap;
overflow: auto;
}
.right-container {
background-color: tomato;
width: 350px;
height: 100%;
}
.column-container {
background-color: red;
width: 150px;
margin: 5px;
display: flex;
flex-direction: column;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<div class="page-container">
<div class="banner">
<div class="banner-title">Title</div>
</div>
<div class="body-container">
<div class="left-container">
<div class="column-container"></div>
<div class="column-container"></div>
<div class="column-container"></div>
<div class="column-container"></div>
<div class="column-container"></div>
<div class="column-container"></div>
<div class="column-container"></div>
<div class="column-container"></div>
</div>
<div class="right-container"></div>
</div>
<div class="footer">Footer</div>
</div>
<script src="./stopwatch.js"></script>
</body>
</html>
Images of desired result:
As unusual an experience as it is likely to cause, you can use a mixture of the flex-direction and order properties to have a scrollable container start on its right-most side.
Like was mentioned in the comments, you will need a container around your columns with flex-direction: row-reverse; to start scrolling from the right. This will place your columns in the opposite order you expect, however.
If you try and use the direction: ltr; style to fix this issue, the scrollbar will again start from the left. Instead, you must set the order property of your columns in reverse. This will take some javascript or server-side templating if you want to avoid unnecessary nth-child selectors.
Here's an example.
.column {
display: flex;
flex-direction: column;
}
.row {
display: flex;
flex-direction: row;
}
#main {
flex-direction: row-reverse;
}
#left {
flex-direction: row-reverse;
overflow-x: scroll;
}
#banner { background-color: lightblue; }
#right { background-color: salmon; width: 400px; }
#left { background-color: teal; }
#footer { background-color: purple; }
<div class="column">
<div class="row" id="banner">Banner</div>
<div class="row" id="main">
<div id="right">Right Container</div>
<div class="row" id="left">
<div class="column" style="order:12">Column Container 1</div>
<div class="column" style="order:11">Column Container 2</div>
<div class="column" style="order:10">Column Container 3</div>
<div class="column" style="order:9">Column Container 4</div>
<div class="column" style="order:8">Column Container 5</div>
<div class="column" style="order:7">Column Container 6</div>
<div class="column" style="order:6">Column Container 7</div>
<div class="column" style="order:5">Column Container 8</div>
<div class="column" style="order:4">Column Container 9</div>
<div class="column" style="order:3">Column Container 10</div>
<div class="column" style="order:2">Column Container 11</div>
<div class="column" style="order:1">Column Container 12</div>
</div>
</div>
<div class="row" id="footer">Footer</div>
</div>
It is not possible to do that with CSS because CSS is made in such a unique way that you can do the things in right manner without any bugs in code .
What you are saying is a behavior opposite to what CSS made for ( which violates its basic rule ) .
Instead you can show the data which user should see first on the left and then he/she can scroll for more on the right side ( This is your best and easy shot) . It will remove other headache like which comes first and last and changing order.
Else you can use JS function to make it possible in opposite way
#import url("https://fonts.googleapis.com/css2?family=Heebo:wght#600&display=swap");
body {
margin: 0;
padding: 0;
}
.page-container {
display: flex;
flex-direction: column;
height: 100vh;
background-color: teal;
align-items: stretch;
flex-direction: column;
}
.banner {
background-color: lightcyan;
position: relative;
width: 100%;
height: 80px;
}
.banner-title {
font-family: "Heebo";
font-weight: 600;
font-size: 40px;
padding: 10px;
}
.footer {
width: 100%;
background-color: thistle;
height: 30px;
}
.body-container {
background-color: lightcyan;
width: 100vw;
height: 100vh;
display: flex;
justify-content: flex-end;
}
.left-container {
background-color: greenyellow;
width: 300px;
display: flex;
overflow: auto;
}
.right-container {
background-color: tomato;
width: 350px;
height: 100%;
}
.column-container {
background-color: red;
width: 150px;
margin: 5px;
padding: 40px;
flex-direction: row-reverse;
direction: rtl
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<div class="page-container">
<div class="banner">
<div class="banner-title">Title</div>
</div>
<div class="body-container">
<div class="left-container">
<div class="column-container"></div>
<div class="column-container"></div>
<div class="column-container"></div>
<div class="column-container"></div>
<div class="column-container"></div>
<div class="column-container"></div>
<div class="column-container"></div>
<div class="column-container"></div>
</div>
<div class="right-container"></div>
</div>
<div class="footer">Footer</div>
</div>
<script src="./stopwatch.js"></script>
</body>
</html>
Using order is the property to change the order of elements without changing position
What is an easy way to make these cards look like that? I want the Y axe to be lower for each card. I tried with padding and calc() but it doesn't work
You can use nth:child to select each of them
.cards {
display: flex;
}
.card {
background-color: red;
width: 100px;
height: 100px;
margin: 0 10px;
}
.card:nth-child(2) {
margin-top: 10px;
}
.card:nth-child(3) {
margin-top: 20px;
}
.card:nth-child(4) {
margin-top: 30px;
}
<div class="cards">
<div class="card">1</div>
<div class="card">2</div>
<div class="card">3</div>
<div class="card">4</div>
</div>
I Think you need a dynamic approach for aligning these elements.
You can use calc function with inline variable.
With nth child approach you have to mention margin for each and every element and later on if you change your mind and want to update margin than you have to update each and every element once again.
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
<style>
.cards {
vertical-align: top;
}
.cards .card {
display: inline-block;
vertical-align:top;
height: 150px;
width: 150px;
border: 1px solid #eaeaea;
margin-top: calc(20px * var(--index) );
}
</style>
</head>
<body>
<div class="cards">
<div class="card" style="--index:1"></div>
<div class="card" style="--index:2"></div>
<div class="card" style="--index:3"></div>
</div>
</body>
</html>
I want to make my div elements be centered in the same line. I want it to be done without using a fixed margin because that doesn't work as soon as you resize it or change screen resolution.
I've tried using "margin: 0 auto" but that didn't seem to work. I've also trid a couple of different things but they were honestly all just me kicking in the dark.
The HTML:
<div class="container div3">
<div class="sredina">
<div class="box">
<img>
<h3></h3>
<p></p>
</div>
<div class="box">
<img>
<h3></h3>
<p></p>
</div>
<div class="box">
<img>
<h3></h3>
<p></p>
</div>
</div>
The CSS:
.box{
text-align: center;
width: 20%;
border: 2px solid blue;
margin: 1pt;
float: left;}
.div3{
text-align: center;}
.sredina{
display: inline-block;
margin: auto;
border: 2px solid red;}
.container{
width: 80%;
margin: auto;
overflow: hidden;
}
How it looks now:
An image of how it looks now
How I want it to look:
An image of how it should look
Use display: flex and justify-content: center on the the .sredina div within your container:
https://codepen.io/HappyHands31/pen/qwvEez
Try to use flex for your .sredina
https://codepen.io/anon/pen/zXbxym
.sredina{
display: flex;
justify-content: center;
align-items: strentch;
margin: auto;
border: 2px solid red;
}
Try this,
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.outer{
background: #87ceeb;
width: 100%;
margin-left: auto;
margin-right: auto;
position: relative;
text-align:center;
}
.inner{
display: inline-block;
min-height: 100px;
height: 100px;
background: chartreuse;
}
</style>
</head>
<body>
<div class="outer">
<div class="inner">hello</div>
<div class="inner">hello</div>
<div class="inner">hello</div>
</div>
</body>
</html>
it works well in all screen sizes. You must use
display: inline-block;
in the inner div class
then use
margin-left: auto;
margin-right: auto;
position: relative;
text-align:center;
in the outer div.
A similar answer is here
Here's the code:
JsFiddle
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="../test.css">
<title>Test title</title>
</head>
<body>
<nav id="user-nav">
<div id="logo-container">
<img src="img/logo.svg" alt="Loading logo">
<p>This is a site</p>
</div>
<div id="form-container">
<i id="search-icon"></i>
<input type="text" name="search" id="form-search" autocomplete="off" placeholder="Quick search...">
</div>
<div class="links">
Home
Services
About
</div>
<div class="profile-link">
Profile name
<div class="drop-menu">
Switch
Log out
</div>
</div>
</nav>
</body>
</html>
and CSS:
* {
margin: 0;
padding: 0;
}
body {
background-color: chocolate;
}
#user-nav {
display: flex;
height: 62px;
position: fixed;
background-color: #333;
width: 100%;
border-bottom: 2px solid #fff;
}
#logo-container img {
width: 96px;
height: 60px;
}
#logo-container {
display: flex;
flex-grow: 2;
}
.profile-link {
flex-grow: 1;
text-align: center;
display: flex;
flex-direction: column;
position: relative;
border-left: 1px solid #fff;
height: 100%;
}
.drop-menu {
display: flex;
flex-direction: column;
position: absolute;
top: 64px;
background: #333;
border-left: 1px solid #fff;
width: 100%;
}
I removed all extra css from other elements in navbar because i thought it was affecting the last divs but it didn't affect the misalignment. I tried different display properties for the div that holds profile name even using list instead of div for drop-down-menu, i always get this offset of 1px. I am styling the navbar using flex because i want to make it more responsive, i am not sure is this somehow affecting the issue.
I am trying to put four elements in four corners of a flex-container using Flexbox and I'm struggling. I can't figure out how to justify the content of individual flex-items. Everytime I try, it ends up putting all content of the flex-container either to the left or right (or top/bottom depending on the main axis).
HTML:
<div class="container">
<div class="top-left">
TL
</div>
<div class="top-right">
TR
</div>
<div class="bottom-left">
BL
</div>
<div class="bottom-right">
BR
</div>
</div>
Here is my CSS:
.container {
display: -webkit-flex;
background-color:#ccc;
}
.top-left {
/* ? */
}
.top-right {
}
.bottom-left {
}
.bottom-right {
}
Here is a fiddle that illustrates what I'm trying to do:
http://jsfiddle.net/JWNmZ/8/
Here is one approach for this (omitted prefixes for clarity): http://jsfiddle.net/JWNmZ/10/
.container {
display: flex;
flex-wrap: wrap;
background-color:#ccc;
}
.top-left {
flex: 50%;
}
.top-right {
flex: 50%;
text-align: right;
}
.bottom-left {
flex: 50%;
}
.bottom-right {
flex: 50%;
text-align: right;
}
#wrapper {
width: 500px;
height: 500px;
background-color: red;
display: flex;
flex-flow: wrap row;
justify-content: space-between;
}
#wrapper>div{
display:flex;
flex-flow:wrap column;
justify-content:space-between;
}
.child {
width: 50px;
height: 50px;
background: yellow;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="wrapper">
<div>
<div class='child'></div>
<div class='child'></div>
</div>
<div>
<div class='child'></div>
<div class='child'></div>
</div>
</div>
</body>
</html>