I'm trying to use the CSS Flexible Box Layout Module to control the order that elements are rendered. Here's some sample HTML (and fiddle):
<div id='outer-container'>
<div id='blue-objects' class='object-container'>
<p>In here we have a number of blue things.</p>
<p>The amount of content could be very small, or very large.</p>
</div>
<div id='green-objects' class='object-container'>
<p>This is very similar to the blue objects block, in that the amount of content is unknown at design-time, and it could be very small or very large.</p>
<p>It could be a complicated, nested set of child objects, although in this example there is nothing more than two <p> elements.</p>
</div>
</div>
/* Started with a columnar layout as given by the Flexplorer: http://bennettfeely.com/flexplorer/ */
.outer-container {
display: -webkit-flex;
display: flex;
-webkit-flex-flow: column wrap;
flex-flow: column wrap;
}
.object-container {
-webkit-flex: 1 auto;
flex: 1 auto;
border: 1px dotted black;
padding: 0 10px;
margin: 10px;
}
#blue-objects {
order: 2;
font-weight: bold;
}
#green-objects {
order: 1;
font-style: italic;
}
My goal is to be able to use pure CSS to control the order the #blue-objects and #green-objects elements appear. All I've been able to accomplish so far is control the horizontal sort order.
The spec describes the order property as follows:
A flex container lays out its content in order-modified document
order, starting from the lowest numbered ordinal group and going up.
I would have thought this would mean that the #green-objects would appear before #blue-objects, because of the order values being 1 and 2, respectively... but it's not working in Chrome 36, Firefox 31, or IE 11.
According to caniuse.com, flexbox has good support in modern browsers. What am I doing wrong? How can I control the order of a vertically stacked set of elements using the CSS Flexible Box Layout module? Help with this fiddle would be greatly appreciated.
You should call #outer-container and not .outer-container in CSS file. Then the flex model will be triggered.
To only put blue objects last, then just apply: order:1; to it and nothing to others:
DEMO
Order defaut value is 0.
Related
Display Flex bug
I'm trying to make this icon just in front of the text but there must be flex and aligin-contet: center; otherwise the text would be such a scatter you will see in the photo where there is a red line so I have already used display:flex; and aligin-content: center; I need to do it somehow so that the icon is still and the show somehow I can't do it I've been doing it for 2 days and they've never helped me yet.
#autocomplete a {
font-weight: bold;
text-decoration: none;
color: #111;
padding: 0.2rem 0.5rem;
border-radius: 20px;
align-items: center;
display: flex;
}
#autocomplete .fa.fa-search {
padding: 5px;
float: left;
}
without Flex and content-aligin: center;
with Flex and content-aligin: center;
you can try using "flex-direction: row-reverse;" it should reverse your items inside the container with the display flex applied.
have a nice day and good luck 😁
My approach would be like this:
Add the following CSS definition:
#autocomplete a * {
vertical-align: middle;
}
The "bold" text is outside a span or similar element. You should also put it into a <span>, so the correct style will be applied to it.
Example:
<a href="./search?q=abcdef&source=autocomplete" data-index="1">
<span class="nobold">abc</span>
<span>def</span>
<i class="fa fa-search"></i>
</a>
(The span around def is the new one.)
Explanation:
The * in the CSS definition in 1. will make the style apply to the selected element and all its children. So, in 2. you just add a matching "child" by using the span. I've tested it and it works for me.
Hint: I don't know if you know about this technique, but you can always use the browser's development tools in order to try such things "on the fly" within the page being shown.
Okay i am working on this and the Ori Guy add me some Idea and i make this code
justify-content: flex-end;
flex-direction: row-reverse;
And look is working :D
Really Thank all who help ME!! THANK YOU <3
I work with BEM and use a flexbox container purely for alignment and responsive design purposes. The problem is that sometimes it also wants to scale its daughter elements, which I don't want. Like this:
.card {
width: 120px;
background: gray;
}
.container {
display: flex;
align-items: center;
}
.flex-item1 {
width: 50px;
background: blue;
}
.flex-item2 {
overflow-wrap: normal;
background: green;
}
.ruller {
width: 50px;
background: gray;
}
<div class='card'>
<div class='container'>
<div class='flex-item1'>
I'm picture 50px wide
</div>
<div class='flex-item2'>
I'm long text
</div>
</div>
</div>
<div class='ruller'>
My width is 50px
</div>
Here is the blue element is getting scaled and its rule width is ignored.
One direct solution for this is to just explicitly forbid flexing for every element.
.flex-item1 {
width: 50px;
background: blue;
flex: none; /* the fix */
}
But container is a general class, I'm using it in tens of different situations, I don't want to add more CSS code to all possible classes of its daughter elements, nor do I want to add another class like container-item to all those elements in HTML.
Another direct solution for this would be
.container * { /* the fix */
flex: none;
}
But this goes against general BEM guidelines on using selectors. I would like to avoid using * selector here.
Is there a way third way to do it? I.e. a way that doesn't add any CSS rules to styles of daughter elements and which does not use * selector.
What makes me ask such a question is the existence of rules like align-items, which are placed to the parent element (i.e. flexbox itself) by the acting on daughter elements (i.e. flex-box items). I imagine my solution would be is something like this:
.container {
display: flex;
align-items: center;
flex-items: none; /* a pseudo rule, which doesn't exist and need to be replaced by other rules to work */
}
If you insist on following BEM without exception, then you should have the rules you need within classes you've defined for your elements. That would be the BEM way. You may not like having that code in 20-30 different places as you say, but that is the tradeoff of BEM.
Personally I combine BEM with utility classes when it makes sense, I don't believe that following BEM blindly to the letter produces cleanest and easiest to maintain codebases.
On the other hand rise in popularity of Tailwind goes to say that BEM and similar methodologies don't work for all.
All this being said, I would suggest sprinkling some utility classes on your BEM project and enjoying best of both worlds.
This question already has an answer here:
List of HTML5 elements that can be nested inside P element?
(1 answer)
Closed 1 year ago.
I have the following code on my page:
.fraction {
vertical-align: middle;
display: inline-block;
}
.frtop, .frbottom {
text-align: center;
}
.frbottom {
border-top: 1px solid;
}
<p style="text-indent: 2em;">
The fraction
<div class="fraction">
<div class="frtop">1</div>
<div class="frbottom">20000</div>
</div>
equals to 0.00005.
</p>
where I am trying to display an inline fraction in an indented paragraph.
However, the fraction is displayed on a separate line: There is a line break between the text The fraction and the fraction itself. How can I fix this?
Note 1: This problem does not occur if I use div instead of p to define my whole paragraph; however, in this case I have to add text-indent: 0; in the CSS code of the .fraction definition and the content does not seem semantically correct to me: I do want to use p to define all my paragraphs.
Note 2: Obviously, I have to replace div with span. However, I need some extra things in the CSS code I provided, so that it works.
Try this :
.fraction {
display: inline-flex;
flex-direction: column;
align-items: center;
text-indent: 0;
vertical-align: middle;
}
.frbottom {
border-top: 1px solid;
}
<p style="text-indent: 2em;">
The fraction
<span class="fraction">
<span>1</span>
<span class="frbottom">20000</span>
</span>
equals to 0.00005.
</p>
Considering the fraction is a part of the paragraph, it shouldn't be in a div anyway.
Edit:
The flex element allows you to display the content either as a row or a column. It's pretty useful for changing classic display.
Since .fraction is in flex, you need align-items to put the content in the middle.
For more information on flex, I would suggest this article: https://css-tricks.com/snippets/css/a-guide-to-flexbox/. This is a very good explanation; much better than everything I could write here :) .
I got a table using flexbox and noticed one interesting feature: the br element can not do anything inside the flexbox.
Example:
.flexbox {
display: flex;
flex-wrap: wrap;
border: 2px solid red;
padding: 2px;
}
.item {
width: 50px;
height: 50px;
margin: 2px;
border: 2px solid blue;
}
.new-row, br {
display: block;
width: 100%;
height: 0px;
}
<p>Line break using div:</p>
<div class="flexbox">
<div class="item"></div>
<div class="item"></div>
<div class="new-row"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<p>Line break using br:</p>
<div class="flexbox">
<div class="item"></div>
<div class="item"></div>
<br>
<div class="item"></div>
<div class="item"></div>
</div>
In the example, div and br share the same properties, but div transfers elements to the new line, and br does not.
Why?
The implementation of the br element in CSS is very well known to be quite the mystery. Different browsers support a different set of properties on the element, to varying degrees of effect (although all of them do support setting display: none to remove it from the layout at least). CSS itself acknowledges this oddity as early as CSS1, having dedicated an entire subsection to it, and even now in CSS3 it's still severely underspecified.
This peculiarity involving flexbox is not new; it has been known since 2014. Basically, in current implementations br does not generate a principal box, but is instead treated as part of a contiguous run of text as described in section 4 of the Flexbox spec, generating an anonymous flex item that cannot be styled (because it's anonymous). This is similar to an orphaned display: table-cell element causing an anonymous table box to be created around it, except you can at least still style the display: table-cell element — in the case of the br element, the style properties you apply have no effect, and the anonymous flex item is laid out with the defaults.
In this case, since br itself is (mostly) empty and it is not being accompanied by any other bare text within the flex container, this results in an anonymous flex item with no dimensions, making it seem as though the br element has vanished completely.
Back in 2014 the CSSWG resolved this "mystery" not by changing the Flexbox spec, but simply to add a special definition for the br element to css-display-3 to account for the behavior seen here. But no such definition exists in the current version of that spec, nor the FPWD (which was published after the resolution!), nor the HTML spec, nor anywhere else. Nevertheless, the definition looks like this in terms of the current css-display-3 spec (which does not define any new properties, just changes the definition of display):
br {
content: '\A';
display: contents;
white-space: pre;
}
... which means that the br element doesn't generate a principal box, but simply an anonymous inline box containing a single newline.
Because this definition is still missing from css-display-3, I wouldn't immediately consider it canon just yet. Even so, the behavior seen here is extremely unlikely to change considering this is how the br element has been for so long.
One other option when using <br> in your code if you just have a single column of elements is to use flex-direction: column.
.flexbox {
display: flex;
flex-wrap: wrap;
border: 2px solid red;
padding: 2px;
flex-direction: column;
}
.item {
width: 50px;
height: 50px;
margin: 2px;
border: 2px solid blue;
}
<p>Line break using br:</p>
<div class="flexbox">
<div class="item"></div>
<br>
<div class="item"></div>
</div>
Unlike Chrome, you must add whitespace ( ) after a <br> in order for it to work in Firefox.
By doing so, you will have the same result in both browsers.
Conlusion:
Works only in Chrome: <br><br><br>
Works in both Chrome and Firefox: <br> <br> <br>
Using flexbox to control the layout of a table works in webkit browsers but in Firefox, <td>s only render as wide as their own content.
Demonstration:
http://codepen.io/afraser/pen/wMgbzr?editors=010
* {
box-sizing: border-box;
}
table {
border: 1px solid #ddd;
width: 100%;
}
tbody {
background: #fff;
}
tr {
display: flex;
}
td:first-child {
flex: 1 1 80%;
background: mistyrose;
}
td:nth-child(2) {
flex: 0 0 10%;
background: Aquamarine;
}
td:nth-child(3) {
flex: 0 0 10%;
background: pink;
}
<table>
<tbody>
<tr>
<td>Ted</td>
<td>1</td>
<td>100%</td>
</tr>
<tr>
<td>Turd Ferguson</td>
<td>2</td>
<td>65%</td>
</tr>
<tr>
<td>Hingle McKringleberry</td>
<td>3</td>
<td>99%</td>
</tr>
</tbody>
</table>
I tried several variations on this including:
Using flex-grow, flex-shrink, and flex-basis individually.
Using pixels for the flex-basis instead of percents.
Using table-layout: fixed.
I see nothing documenting this here: https://github.com/philipwalton/flexbugs and have come up dry elsewhere. Does anyone know what's going on?
That's because, according to CSS tables, anonymous table objects should be generated when tabular elements are not children of a table:
According to the Flexbox Last Call Working Draft, it was that anonymous table what became the flex item, not the table cells:
Some values of display trigger the creation of anonymous boxes
around the original box. It’s the outermost box—the direct child of
the flex container box—that becomes a flex item. For
example, given two contiguous child elements with display: table-cell, the anonymous table wrapper box generated around
them [CSS21] becomes the flex item.
Since the table cells were not flex items, they ignored the flex property. It would apply to the anonymous table, but CSS selectors can't select anonymous elements.
However, Chrome disagreed with the spec and decided to blockify the table cells instead.
Then the CSS working group decided to standardize Chrome's behavior:
If you have a flex container and you put two table cells in it, they
won't become flex items independently. They'll wrap in an anonymous
table and that will be flex.
However, Chrome had implemented it so that each item is independently
a flex item. [...] So it turns the table cells into blocks.
I've seen at least one presentation at a conference where they took
advantage of this to create fallback behavior for a flex. [...] If you're
not trying to trigger fallback, I don't know why you'd put a bunch of
table cells in flex and get it wrapped in anonymous stuff. [...]
RESOLVED: Just blockify the children of flex and grid containers.
Don't do anonymous box fix-up
The first Flexbox Candidate Recommendation was published with that new resolution:
Some values of display normally trigger the creation of
anonymous boxes around the original box. If such a box is a flex
item, it is blockified first, and so anonymous box creation will
not happen. For example, two contiguous flex items with
display: table-cell will become two separate display: block flex items, instead of being wrapped into a single
anonymous table.
And then Firefox implemented the new behavior starting at version 47 (bug 1185140).
For older versions, you can style the cells as blocks manually:
.flex-container > td {
display: block;
}
* {
box-sizing: border-box;
}
table{
border: 1px solid #ddd;
width: 100%;
}
tbody {
background: #fff;
}
tr {
display: flex;
}
td {
display: block;
}
td:first-child {
flex: 1 1 80%;
background: mistyrose;
}
td:nth-child(2){
flex: 0 0 10%;
background: Aquamarine;
}
td:nth-child(3){
flex: 0 0 10%;
background: pink;
}
<table>
<tbody>
<tr>
<td>Ted</td>
<td>1</td>
<td>100%</td>
</tr>
<tr>
<td>Turd Ferguson</td>
<td>2</td>
<td>65%</td>
</tr>
<tr>
<td>Hingle McKringleberry</td>
<td>3</td>
<td>99%</td>
</tr>
</tbody>
</table>
I believe the issue involves the default display value of your flex items.
If you override it with display: flex the layout should work as intended across browsers.
Make the following adjustments:
td:first-child { display: flex; }
td:nth-child(2) { display: flex; }
td:nth-child(3) { display: flex; }
Revised Codepen
My first thought was to make sure each td had the proper display value applied – something along the lines of display: flex-item. However, flex-item doesn't exist, so I used display: flex.
EDIT
The solution above stands. This edit pertains to the explanation.
On examination of the spec, it appears that flex items don't even have a default display value. Basically, once you make the parent a flex container, the children become flex items, and accept flex properties, regardless of any display rule applied. Hence, a default display rule is not necessary.
In this case, it seems that having to declare display: flex on the flex items is a quirk necessary to get Firefox and IE to work.