Say you have the following data points that are dumped from a database or file, the size of each item representing the amount of something (hours, pizzas, whatever)...
And you would like to organize the data into categories like so using CSS...
How would you do it?
I tried the grid shepard method using grid-rowbut get this instead...
Thanks!
P.S. follow up question... My intuition is that CSS would be faster than JS (...moving each item into the appropriate flexbox that could then sort row members horizontally). Is that true? Is CSS likely to be faster in a dataset of possibly thousands of elements?
You can use the flexbox with order.
This is a guide for the flexbox: https://css-tricks.com/snippets/css/a-guide-to-flexbox/
check this sample:
.wrapper {
display: flex;
flex-flow: row wrap;
}
.wrapper > * {
padding: 10px;
flex: 1 0 100%;
}
.o-1,.o-3,.o-5,.o-7 {
background: gold;
}
.o-2,.o-4,.o-6 {
background: hotpink;
}
.o-1 { order: 1; }
.o-2 { order: 2; }
.o-3 { order: 3; }
.o-4 { order: 4; }
.o-5 { order: 5; }
.o-6 { order: 6; }
.o-7 { order: 7; }
<div class="wrapper">
<aside class="o-1">1</aside>
<aside class="o-3">3</aside>
<aside class="o-2">2</aside>
<aside class="o-4">4</aside>
<aside class="o-7">7</aside>
<aside class="o-5">5</aside>
<aside class="o-6">6</aside>
</div>
Related
I have a design brief which requires me to move the red component (on the right) to the red frame/shell(on the left).
The two categories/sections comes from a REST-API, with their children in side like that.
[ What i've tried ]
I tried positioning the red component absolute, but the problem was that if the content of the component above it grow. the two components are going to overlap.
I couldn't find exactly where to position it. (in terms on Y axis)
[ What i would like ]
I was hoping that maybe i can use v-slot to create a shell/frame on the left, then i template the component on the right and yield it to the shell/frame on the left side.
Any help would be appreciated.
Thanks in advance.
If I understand you correctly, that's what you need :
// sorry for plain css, I just don't know how insert scss in stackoverflow snippet box
const btn = document.querySelector('button')
const grid = document.querySelector('.grid')
btn.onclick = () => grid.classList.toggle('replaced')
.grid {
display: grid;
grid-template-columns: 100px 100px;
grid-template-rows: 100px 100px;
column-gap: 20px;
row-gap: 20px;
}
div {
background: black;
}
div:nth-child(1) {
order: 10;
}
div:nth-child(2) {
order: 20;
}
div:nth-child(3) {
order: 30;
}
div:nth-child(4) {
order: 40;
background: red;
}
.replaced div:nth-child(4) {
order: 11;
}
<main class="grid replaced">
<div></div>
<div></div>
<div></div>
<div></div>
</main>
<button>toggle</button>
I am trying to break some elements in different order on mobile, i have something like this now
And my html
<main>
<div data-color="yellow"></div>
<div class="wrapper">
<div data-color="orange"></div>
<div data-color="purple"></div>
</div>
</main>
Here is my css
.wrapper {
flex-direction: column;
}
div {
flex: 1;
}
[data-color=purple] {
order: 3;
}
main.mobile {
flex-direction: column;
}
main.mobile .wrapper {
display: contents;
}
main.mobile [data-color=orange] {
order: -2;
}
I made it simple that you can help me, what i need is that now palge lpaut is half and half, i need yellow container to be 75% and right 25%, i am using boostrap 4 but I am not so good at fex layout
Thanks
main {
display: flex;
}
[data-color="yellow"] {
flex: 0 0 75%;
}
.wrapper{
flex: 0 0 25%;
}
you can use flex: 1 percentage(); for example flex: 1 percentage(1/4);
Here I made an example in codepen for you:
https://codepen.io/Alirezaaraby/pen/JjYJMZW?editors=1100
I'm trying to accomplish the following layout:
My first thought is to use flexbox to achieve this layout. I currently have the following HTML:
<section>
<div class"item">box1</div>
<div class"item">box2</div>
<div class"item">box3</div>
<div class"item">box4</div>
<div class"item">box5</div>
</section>
How can I achieve the desired layout with my HTML? I can add line break div elements in between items like this as well:
<div class"break"> </div>
Unfortunately I am still not able to achieve the required layout. Please help
A simple CSS-grid based approach would be to use a "template of named grid areas".
CSS grid allows for named areas, which dictate the placement of children based on the grid-area of those grid children. In the case of your requirements, a template based on named areas could be defined as:
grid-template-areas:
"a a b b c c"
". . e f . .";
These template areas work by causing:
child elements with grid-area of a, b, and c to occupy the top row of the template layout, where each spans two columns of the 6 column grid
child elements with grid-area of e and f to occupy the bottom row of the template, at the third and fourth column respectively. The . on this row configuration specifies that no child apples to that area of the template
Note that template area strings can be written on the same line for the grid-template-areas property as shown below:
section {
/* Specify that CSS grid is to be used for layout of children */
display: grid;
/* Specify spacing between children */
grid-gap:1rem;
/* Wrap against six evenly spaced columns of this grid */
grid-template-columns: repeat(6, 1fr);
/* Define the area names of the grid template */
grid-template-areas: "a a b b c c" ". . e f . .";
}
section div:nth-child(1) {
grid-area: a;
}
section div:nth-child(2) {
grid-area: b;
}
section div:nth-child(3) {
grid-area: e;
}
section div:nth-child(4) {
grid-area: f;
}
section div:nth-child(5) {
grid-area: c;
}
/* Optional aesthetics to better match your example */
div {
background: darkgrey;
border-radius: 5px;
color: white;
text-align: center;
}
<section>
<div class "item">box1</div>
<div class "item">box2</div>
<div class "item">box3</div>
<div class "item">box4</div>
<div class "item">box5</div>
</section>
Updates
section {
display: grid;
grid-gap:1rem;
grid-template-columns: repeat(5, auto);
grid-template-areas: "a b c c d e" ". . f g . .";
}
section div:nth-child(1) {
grid-area: a;
}
section div:nth-child(2) {
grid-area: b;
}
section div:nth-child(3) {
grid-area: c;
}
section div:nth-child(4) {
grid-area: f;
}
section div:nth-child(5) {
grid-area: g;
}
section div:nth-child(6) {
grid-area: d;
}
section div:nth-child(7) {
grid-area: e;
}
/* Optional aesthetics to better match your example */
div {
background: darkgrey;
border-radius: 5px;
color: white;
text-align: center;
}
<section>
<div class "item">box1</div>
<div class "item">box2</div>
<div class "item">box3</div>
<div class "item">box4 lots of content causes uneven column distribution</div>
<div class "item">box5</div>
<div class "item">box6</div>
<div class "item">box7</div>
</section>
You Can use CSS Grid Instead:
Complete Grid Guide
Working Demo:
.grid {
display: grid;
grid-template-areas: "i1 i1 i2 i2 i3 i3" ". . i4 i5 . .";
grid-template-columns: repeat(6,1fr); /* to make all boxes same with */
grid-gap: 10px;
}
.i1 {
grid-area: i1
}
.i2 {
grid-area: i2
}
.i3 {
grid-area: i3
}
.i4 {
grid-area: i4
}
.i5 {
grid-area: i5
}
.item {
min-height: 40px;
background-color: #7D7D7D;
border-radius: 10px;
display: flex;
justify-content: center;
;
align-items: center;
color: white;
font-size: 1.5rem;
font-weight: bolder;
}
.i4,.i5 {
border-radius: 8px;
}
<section class="grid">
<div class="item i1">box1</div>
<div class="item i2">box2</div>
<div class="item i3">box3</div>
<div class="item i4">box4</div>
<div class="item i5">box5</div>
</section>
With flexbox you can adjust the order of the element and rely on wrapping:
section {
display:flex;
flex-wrap:wrap;
justify-content:center;
}
section > .item {
width:calc(100%/3 - 10px);
margin:5px;
}
section > .item:nth-child(3),
section > .item:nth-child(4){
order:1;
width:calc((100%/3 - 20px) /2);
}
/* Irrelevant styles */
section > .item {
padding:10px;
box-sizing:border-box;
text-align:center;
background:#000;
color:#fff;
border-radius:10px;
}
<section>
<div class="item">box1</div>
<div class="item">box2</div>
<div class="item">box3</div>
<div class="item">box4</div>
<div class="item">box5</div>
</section>
While using the old CSS grid spec that is supported by IE 11 and EDGE. Is it possible for the grid items to be auto placed like the current spec?
i.e. to not have to define the column on a grid item:
.item:nth-child(1) {
-ms-grid-column: 1;
}
.item:nth-child(2) {
-ms-grid-column: 2;
}
.item:nth-child(n) {
-ms-grid-column: n;
}
https://codepen.io/JoeHastings/pen/mMPoqB
The answer is NO (unfortunately).
Old specs section about auto-placement has such preamble
This section describes early thinking around automatic placement of Grid Items. Multiple algorithms are possible for such a feature. One is proposed here.
Run this code in IE/Edge and you'll see a lot of rows with 1 in console because IE/Edge stacks all grid items in first cell and you can't force IE/Edge to place grid items automatically. Setting -ms-grid-column and -ms-grid-row to auto won't change anything, because this value is not supported (as you can see in MSDN links). Demo:
var gridItems = document.querySelectorAll(".grid__item");
for (var i = 0; i < gridItems.length; i++) {
var gridItem = gridItems[i];
console.log(window.getComputedStyle(gridItem)["-ms-grid-row"]);
console.log(window.getComputedStyle(gridItem)["-ms-grid-column"]);
}
.grid {
display: -ms-grid;
-ms-grid-columns: 100px 100px 100px;
-ms-grid-rows: 100px 100px 100px;
}
.grid__item {
-ms-grid-row: auto;
-ms-grid-column: auto;
background-color: tomato;
color: white;
font-size: 20px;
display: flex;
align-items: center;
justify-content: center;
}
<div class="grid">
<div class="grid__item">One</div>
<div class="grid__item">Two</div>
<div class="grid__item">Three</div>
<div class="grid__item">Four</div>
<div class="grid__item">Five</div>
<div class="grid__item">Six</div>
<div class="grid__item">Seven</div>
<div class="grid__item">Eight</div>
<div class="grid__item">Nine</div>
</div>
I am trying to use CSS to calculate the top height to add every 5+1 elements.
The following code moves a series of absolute positioned elements to their respective places.
.screen [data-app]:nth-child(5n-4) { left:0%; }
.screen [data-app]:nth-child(5n-3) { left:20%; }
.screen [data-app]:nth-child(5n-2) { left:40%; }
.screen [data-app]:nth-child(5n-1) { left:60%; }
.screen [data-app]:nth-child(5n) { left:80%; }
This creates the illusion of five columns with absolutely positioned elements. Now what I'd like to do is for the next row of five to also have top:180px added to them, and the row after that top:360px etc.. etc..
Can this be done without the need to write CSS code for the position of every single element. Some way of applying a top attribute for each group of five based on n value of the current element.
You can either use SASS or Flexbox in order to achieve the result you're looking for. In this case SASS will create a more bloated CSS-file than ideal, but will use the rules you posit, while Flexbox will be more future-proof and easily maintained.
The HTML
<div class="screen">
<div data-app>asdf1</div>
<div data-app>asdf2</div>
<div data-app>asdf3</div>
<div data-app>asdf4</div>
<div data-app>asdf5</div>
<div data-app>asdf6</div>
<div data-app>asdf7</div>
<div data-app>asdf8</div>
<div data-app>asdf9</div>
<div data-app>asdf10</div>
<div data-app>asdf11</div>
</div>
SASS
.screen {
position: relative;
}
.screen [data-app] {
$height: 180px;
$offset: 20%;
$blocks_per_row: 5;
position: absolute;
width: 20%;
#for $i from 0 through 20 {
$y: floor($i / $blocks_per_row);
$x: $i % 5;
&:nth-child(#{$y}n+#{$i}) {
left: $x * $offset;
top: $y * $height;
}
}
}
Flexbox
.screen {
display: flex;
flex-flow: row wrap;
justify-content: flex-start;
align-content: flex-start;
align-items: flex-start;
}
.screen [data-app] {
flex: 0 1 20%;
height: 180px;
}
As you can see, there's no upper limit in the Flexbox solution and it's very clean. I hope any of these solutions help you.