I am tring to display two div inside a nav on the rigth, the problem is that if I set this div <div _ngcontent-c9="" class=" ng-clock docs-homepage-row menuSup"> as float: right in the css, it will not goes on the right part of the screen.
<nav _ngcontent-c1="" class=" ng-clock docs-navbar-header menuDate">
<div _ngcontent-c9="" class=" ng-clock docs-homepage-row menuSup">
<div _ngcontent-c9="" class=" ng-clock docs-homepage-promo-img">
...
</div>
<div _ngcontent-c9="" class=" ng-clock docs-homepage-promo-img" >
...
</div>
</div>
</nav>
CSS
.docs-navbar-header[_ngcontent-c1] {
display : flex;
flex-wrap : wrap;
align-items : center;
padding : 12px 16px;
}
.menuDate{
width: 100%;
background: var(--defaultColorDark);
}
.docs-homepage-row[_ngcontent-c9] {
display : flex;
max-width : 920px;
margin : 60px 0;
float: right;
}
.menuSup[_ngcontent-c9] {
display : flex;
width: 100%;
margin : 10px 10px;
float: right;
}
.docs-homepage-row[_ngcontent-c9] .docs-svg-image[_ngcontent-c9] {
max-width : 90%;
}
.docs-homepage-promo-desc[_ngcontent-c9], .docs-homepage-promo-img[_ngcontent-c9] {
width : 50%;
}
.docs-homepage-promo-img[_ngcontent-c9] {
text-align : center;
margin-top: 20px;
}
There is many options to achieve what you need, but using float property is not the best one. Each following options will be interesting depending of the context.
[OPTION #1] (recommended)
If .docs-homepage-row.menuSup is the only one child of .docs-navbar-header.menuDate, you can simply apply justify-content: flex-end; to .docs-navbar-header.menuDate.
Learn more about Flexbox there : https://css-tricks.com/snippets/css/a-guide-to-flexbox/
[OPTION #2] (usefull)
Apply margin-left: auto; to .docs-homepage-row.menuSup will push the flex-item to the right.
[OPTION #3] (not recommended)
If, for some reason, you really need to use float, be aware that you need to "clear" the next element. The best way to achieve it, it's to use the clearfix hack on the parent.
You can learn more about the clearfix hack on the following link : https://css-tricks.com/snippets/css/clear-fix/
Related
Hello I'm not too good with css/floats/blocks etc.
I have this sort of setup
<div class="blue">1</div>
<div class="red">2</div>
<div class="blue">3</div>
<div class="red">4</div>
<div class="blue">5</div>
<div class="red">6</div>
I want to style it so 1 and 2 are on the same line (floated left and right), then 3 and 4 are on the same line (floated left and right) and so on and so forth.
Currently these elements are created in a loop. I have tried all sorts of methods to get the elements to line up how I want to no avail.
I think you want to make them two per row correct?
You can add a flex property to the parent container. Set the flex-wrap to wrap, then add a 50% width on your child elements (taking into account any inherited margin or padding effecting the layouts width to not overflow the flex-wrap), then justify-content to space-between, this will force the elements to their respective sides or a better way to put it is; place the "left over" space the children on that row are not taking up, in the middle of the two elements.
* { /* set box-sizing on all elements to border-box */
box-sizing: border-box;
}
body { /* remove any margin or padding from the body */
margin: 0;
padding: 0;
}
#cont { /* add display flex, flex-wrap and justify-content to space between */
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
#cont>div { /* Set your child divs to a percentage that will only give you two per row
the flex-wrap will push elements down */
width: 50%;
}
.blue {
background-color: lightblue;
border: 1px solid darkblue;
}
.red {
background-color: pink;
border: 1px solid darkred;
text-align: right; /* remove if you want standard left side text-alignment on red elements */
}
<div id="cont">
<div class="blue">1</div>
<div class="red">2</div>
<div class="blue">3</div>
<div class="red">4</div>
<div class="blue">5</div>
<div class="red">6</div>
</div>
If this is not what you were looking for let me know and I can edit or remove this answer.
My problem is that I want the flexbox with variable range width, and all works well, but not on the last row. I want the same dimension for all children even where the row is not full of children (the last row).
#products-list {
position:relative;
display: flex;
flex-flow: row wrap;
width:100%;
}
#products-list .product {
min-width:150px;
max-width:250px;
margin:10px 10px 20px 10px;
flex:1;
}
I created a dynamic situation in jsFiddle
My flex divs can shrink until 150px and grow up to 250px, but all must be with the same size (and obviously I want a CSS solution, with JS I know the way).
Unfortunately, in the current iteration of flexbox (Level 1), there is no clean way to solve the last-row alignment problem. It's a common problem.
It would be useful to have a flex property along the lines of:
last-row
last-column
only-child-in-a-row
alone-in-a-column
This problem does appear to be a high priority for Flexbox Level 2:
CSS Working Group Wiki - Specification Issues and Planning
https://lists.w3.org/Archives/Public/www-style/2015Jan/0150.html
Although this behavior is difficult to achieve in flexbox, it's simple and easy in CSS Grid Layout:
Equal width flex items even after they wrap
In case Grid is not an option, here's a list of similar questions containing various flexbox hacks:
Properly sizing and aligning the flex item(s) on the last row
Flex-box: Align last row to grid
Flexbox wrap - different alignment for last row
How can a flex item keep the same dimensions when it is forced to a new row?
Selector for an element alone in a row?
Aligning elements in last flexbox row
How can I allow flex-items to grow while keeping the same size?
Left-align last row of flexbox using space-between and margins
Inconsistent margin between flex items on last row
How to keep wrapped flex-items the same width as the elements on the previous row?
How to align left last row/line in multiple line flexbox
Last children of grid get giant gutter cause of flexbox space-between
Managing justify-content: space-between on last row
Flexbox space between behavior combined with wrap
Possible to use CSS Flexbox to stretch elements on every row while maintaining consistent widths?
As a quick and dirty solution one can use:
.my-flex-child:last-child/*.product:last-child*/ {
flex-grow: 100;/*Or any number big enough*/
}
You could try using grid instead of flexbox here:
#products-list {
display: grid;
grid-gap: 5px;
grid-template-columns: repeat(auto-fit, minmax(100px, 250px)); //grid automagic
justify-content: start; //start left
}
Fiddle link
There is a great solution that works always.
add a div with class product (The same class for other items that are under flex) and add a style for this div:height:0px;
you need to add as many dives that are possible to be in one row.
<div class="product" style="height:0px">
as many that can be in one row.
That's all. Works always.
If all your rows have the same number of items, you can use :nth-last-child. For example, if all the rows have 3 items, you can do something like this to remove the margin of the last 3 items:
.container{
display: flex;
flex-wrap: wrap;
background: yellow;
}
.item{
width: calc((100% - 2*10px)/3);
height: 50px;
background: blue;
color: white;
margin-right: 10px;
margin-bottom: 10px;
padding: 5px;
box-sizing: border-box;
}
/* last item of each row */
.item:nth-child(3n){
margin-right: 0;
font-size: 150%;
}
/* last 3 items */
.item:nth-last-child(-n+3){
margin-bottom: 0;
background: green;
}
<div class="container">
<div class="item" >1</div>
<div class="item" >2</div>
<div class="item" >3</div>
<div class="item" >4</div>
<div class="item" >5</div>
<div class="item" >6</div>
<div class="item" >7</div>
</div>
A simple trick adds a flexible space to fill the rest of the last row:
#products-list{
display:flex;
flex-flow: row wrap;
justify-content:space-between;
}
#products-list::after {
content: "";
flex: auto;
flex-basis: 200px;/*your item width*/
flex-grow: 0;
}
But you shouldn't use margins on items then. Rather wrap them into containers with padding.
I used this workaround, even if it's not very elegant and it doesn't use the power of Flexbox.
It can be carried out on the following conditions:
All the items have the same width
The items have a fixed width
You use SCSS/SASS (can be avoided though)
If this is the case, you can use the following snippet:
$itemWidth: 400px;
$itemMargin: 10px;
html, body {
margin: 0;
padding: 0;
}
.flex-container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
margin: 0 auto;
border: solid 1px blue;
}
#for $i from 1 through 10 {
#media only screen and (min-width: $i * $itemWidth + 2 * $i * $itemMargin) {
.flex-container {
width: $i * $itemWidth + 2 * $i * $itemMargin;
}
}
}
.item {
flex: 0 0 $itemWidth;
height: 100px;
margin: $itemMargin;
background: red;
}
<div class="flex-container">
<div class="item"></div>
<div class="item" style="flex: 500 0 200px"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
Here I have created an example on codepen which also implements margin.
The second and the third conditions can be avoided respectively using css variables (if you decided to provide support for it) and compiling the above scss snippet.
Well, it's true, we could do it also before flexbox, but display: flex can be still essential for a responsive design.
I was facing this same issue where I wanted to have a variable number of items in a resizable container.
I wanted to use all of the horizontal space, but have all of the flex items at the same size.
I ultimately came up with a javascript approach that dynamically added padding spacers as the container was resized.
function padLastFormRow() {
let topList = [];
let nSpacersToAdd = 0;
$('#flexContainer').find('.formSpacer').remove();
$('#flexContainer').find('.formItem').each(function(i, formItem) {
topList.push($(formItem).position().top);
});
let allRowLengths = getFlexLineLengths(topList);
let firstRowLength = allRowLengths[0];
let lastRowLength = allRowLengths[((allRowLengths.length) - 1)];
if (lastRowLength < firstRowLength) {
nSpacersToAdd = firstRowLength - lastRowLength ;
}
for (var i = 1; i <= nSpacersToAdd; i ++) {
$('#flexContainer').append(formSpacerItem);
}
}
Please see my Fiddle:
http://jsfiddle.net/Harold_Buchman/z5r3ogye/11/
I was having a similar challenge with menu rows. I wanted more spacing on the top of the second row of menu items.
The use of flex-box's row-gap worked well.
https://developer.mozilla.org/en-US/docs/Web/CSS/row-gap
.menu {
display: flex;
flex-wrap: wrap;
row-gap: 10px;
}
This added a margin-top type effect to menu items were wrapped to the second line.
If all your rows have the same number of items, you can use :nth-last-child. For example, if all the rows have 3 items, you can do something like this:
.container{
display: flex;
flex-wrap: wrap;
background: yellow;
}
.item{
width: calc((100% - 2*10px)/3);
height: 50px;
background: blue;
color: white;
margin-right: 10px;
margin-bottom: 10px;
padding: 5px;
box-sizing: border-box;
}
// last item of each row
.item:nth-child(3n){
margin-right: 0;
background: green;
}
// last 3 items
.item:nth-last-child(-n+3){
margin-bottom: 0;
font-size: 150%;
}
<div class="container">
<div class="item" >1</div>
<div class="item" >2</div>
<div class="item" >3</div>
<div class="item" >4</div>
<div class="item" >5</div>
<div class="item" >6</div>
<div class="item" >7</div>
</div>
I am working on react web app which has less styling, so under
wrapper I have 3 columns, such that leftWrap is col-3, rightWrap is
col-4, and rest width is centerWrap. How can i apply flex while i just
know its col-* classnames
<div className={styles.Home__wrapper}>
<div className={styles.Home__leftWrap}> .... </div>
<div className={styles.Home__centerWrap}> .... </div>
<div className={styles.Home__rightWrap}> .... </div>
</div>
.Home {
&__wrapper {
display : flex;
flex-wrap: nowrap;
width : 100%;
box-sizing: border-box;
}
&__leftWrap {
display : flex;
}
&__rightWrap {
display : flex;
}
&__centerWrap {
display : flex;
}
}
How to set width to each column className as per above mentioned, is
it through cal() method
Set the display CSS attribute on the container div to flex, and play with the flex attribute on the children elements. Flex will sum up the flex number assigned to each children element to calculate the "total" steps to be filled, then calculate the value of each step based on the available space remaining and calculate the display width of each child by multiplying the calculated step width value by the child element flex value. In your case, it looks like your left and right children have fixed widths, and you want the center element to take the remaining space, so just set flex to 1 on the center element.
._wrapper {
display : flex;
flex-wrap: nowrap;
box-sizing: border-box;
}
._leftWrap {
width: 50px;
background-color: red;
}
._rightWrap {
width: 100px;
background-color: blue;
}
._centerWrap {
flex: 1;
background-color: yellow;
}
<div class="_wrapper">
<div class="_leftWrap"> .... </div>
<div class="_centerWrap"> .... </div>
<div class="_rightWrap"> .... </div>
</div>
I'm using display flex to display multiple items in one big container (parentDiv). The code is working fine but I get big problems with horizontal centering the items (especially If there are only a few items they should get horizontally centered) so I was using justify-content what leads to big issues:
The parent div is not able to display all items anymore. The first item that gets displayed is the item "04" while it should be "01". How to avoid this?
Please have a look at this code:
#bigDiv {
position: absolute;
width: 100%;
height: 100%;
}
#parentDiv {
width: 90%;
height: 50%;
overflow-y: hidden;
overflow-x: scroll;
text-align: center;
white-space: nowrap;
background: red;
display: flex;
justify-content: center;
align-items: center;
}
.item {
color: white;
background: blue;
flex: 0 0 4%;
margin: 0 3%;
}
.item::after {
content: "";
display: block;
padding-bottom: 100%;
}
<div id="bigDiv">
<div id="parentDiv">
<div class="item">01</div>
<div class="item">02</div>
<div class="item">03</div>
<div class="item">04</div>
<div class="item">05</div>
<div class="item">06</div>
<div class="item">07</div>
<div class="item">08</div>
<div class="item">09</div>
<div class="item">10</div>
<div class="item">11</div>
<div class="item">12</div>
<div class="item">13</div>
<div class="item">14</div>
<div class="item">15</div>
<div class="item">16</div>
</div>
</div>
See this image:
My intentions: The parent div should be able to show all of the items (starting with "01" - and the last element should be the "16"-one)
Note: If there are only 4 or less items they should get centered horizontally. (The reason why I added justify-content).
You're fiting 160% into 100%. And you want it centered. And it works: the 160% total width of the resulting children is nicely centered.
But you're also expecting whatever is outside the parent to be accessible.
It's pretty much like making a child element go outside of its parent by -30% to the left or to the top (by any other method) and expecting the parent to allow you to scroll to it. It's not going to happen!
If it did, the child would no longer be placed at -30%, it would be placed at 0%. Scrollbars will never scroll to left or top negative space. It's by design. You need to take it into consideration when designing your page.
Whenever you center a bigger child into a smaller parent you won't be able to use parent's scrollbars to scroll to the beginning of the child. So anything preventing the child positioning in the parent's left negative space will fix it.
I have a div that it's direction is determined by the content it hosts (using dir="auto"). I would like to use CSS (if it's impossible than javascript) to determine the direction and change the absolute position of the delete span accordingly.
see here in this fiddle: https://jsfiddle.net/psjgsnby/
<div dir="auto" class="item">
text
<span>x</span>
</div>
<div dir="auto" class="item">
מימין לשמאל
<span>x</span>
</div>
css:
.item {
position: relative;
width: 200px;
}
.item span {
position: absolute;
right: 0;
top: 0;
}
i'm looking for something like this selector:
.item span:dir(rtl) {
right: auto;
left: 0;
}
but something that works cross-browser (the above works only for firefox)
Using dir="auto" gives the browser the ownership on detecting which direction to use, based on the content of the element.
Note that different browsers might give different results, based on implementation.
The dir=auto actually tells the browser to:
look at the first strongly typed character in the element and work out from that what the base direction of the element should be. If it's a Hebrew (or Arabic, etc.) character, the element will get a direction of rtl. If it's, say, a Latin character, the direction will be ltr.
In CSS you don't really have an option to check this, but if you want to use javascript you can try to do exactly the same. Find the first character that is strongly typed, and based on that use the relevant direction. The only question you got here is which languages you want to support.
I found a solution but its very far from your code. Its base on display: table because we need a dynamic direction flow for every element.
Don't forget, you can change the vertical align for different positions.
.item {
display: table;
width: 200px;
height: 50px;
}
.item .btn,
.item .content {
display: table-cell;
}
.item .btn {
vertical-align: top;
}
.item .content {
width: 100%;
vertical-align: bottom;
}
<div dir="auto" class="item">
<span class="content">text</span>
<span class="btn">
x
</span>
</div>
<div dir="auto" class="item">
<span class="content">מימין לשמאל</span>
<span class="btn">
x
</span>
</div>
Fiddle demo
If you change the display of the container to flex, this is easily achievable. You just need justify-content: space-between:
The CSS is even more compact that what you had:
.item {
position: relative;
display: flex;
width: 200px;
justify-content: space-between;
}
<div dir="auto" class="item">
text
<span>x</span>
</div>
<div dir="auto" class="item">
מימין לשמאל
<span>x</span>
</div>