Snake-like alignment in css
If you create your HTML structure with parent
- rows
- items
you can use flex-direction: row-reverse
on .row:nth-child(2n)
elements and that will create desired result.
.content { display: flex; flex-direction: column;}.row { display: flex; justify-content: space-between;}.row:nth-child(2n) { flex-direction: row-reverse;}.row:nth-child(2n):last-child .item { margin-right: auto;}
<div class="content"> <div class="row"> <div class="item">1</div> <div class="item">2</div> <div class="item">3</div> </div> <div class="row"> <div class="item">4</div> <div class="item">5</div> <div class="item">6</div> </div> <div class="row"> <div class="item">7</div> <div class="item">8</div> <div class="item">9</div> </div> <div class="row"> <div class="item">10</div> </div></div>
How can I reverse flexbox direction on wrap to achieve snake wrap?
A CSS grid solution similar to this one that works with a fixed number of elements per row (aka fixed number of columns).
.flex-container { width: 500px; background: orange; display: grid; grid-template-columns:repeat(5,1fr); /*define the number of column*/ grid-auto-flow:dense; /* this is important to fill all the space*/ grid-gap:20px; padding:10px;}
.item { background: purple; height: 80px; line-height: 80px; color: white; font-weight: bold; font-size: 2em; text-align: center;}
.item:nth-child(10n + 6) {grid-column:5}.item:nth-child(10n + 7) {grid-column:4}.item:nth-child(10n + 8) {grid-column:3}.item:nth-child(10n + 9) {grid-column:2}/*.item:nth-child(10n + 10) {grid-column:1} not needed*//* For N = number of columns .item:nth-child((2xN)n + (N+1)) { grid-column:N; } .item:nth-child((2xN)n + (N+2)) { grid-column:(N-1); } .... .item:nth-child((2xN)n + (2xN)) { grid-column:1; }
*/
.item:before { content:counter(num); counter-increment:num;}body { font: 400 14px 'Arial', sans-serif; counter-reset:num;}
<div class="flex-container"> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div></div>
How to make a border going left and right like a snake around my articles list?
A neat way to make this work would be to make use of pseudo-elements like ::before
or ::after
in which you could display the border with an offset on the sides that you simply can't achieve when relying on the box-model.
It would look like this:
.article-container {
position: relative;
padding: 10px;
}
.article-container:not(:last-child) {
margin-bottom: -5px;
}
.article-container::before {
content: "";
position: absolute;
top: 0;
bottom: 0;
border-top: 5px solid #df9b35;
border-bottom: 5px solid #df9b35;
}
.article-container.left {
padding-left: 30px;
}
.article-container.left::before {
right: 50px;
left: 0;
border-left: 5px solid #df9b35;
border-radius: 50px 0 0 50px;
}
.article-container.right {
padding-right: 30px;
}
.article-container.right::before {
left: 50px;
right: 0;
border-right: 5px solid #df9b35;
border-radius: 0 50px 50px 0;
}
<section>
<div class="article-container left">
<article class="card-container time-item">
<header>
<h1>Article 1</h1>
<time datetime="2022-08-18 15:55">18 August</time>
</header>
<p>Short description here</p>
</article>
</div>
<div class="article-container right">
<article class="card-container time-item">
<header>
<h1>Article 2</h1>
<time datetime="2022-08-18 16:00">18 August</time>
</header>
<p>Short description here</p>
</article>
</div>
<div class="article-container left">
<article class="card-container time-item">
<header>
<h1>Article 3</h1>
<time datetime="2022-08-18 16:05">18 August</time>
</header>
<p>Short description here</p>
</article>
</div>
</section>
Snake-like border animation
Since the border consists of exactly two separate line segments, ::before
and ::after
may be sufficient to do the trick!
This is overall a question of messing with @keyframes
. The following example shows:
- leftmost: only
::before
, "head" element showing - middle: only
::after
, "tail" element showing - rightmost: both pseudo-elements; this is the final result
body { background-color: #000000; }
.ex1, .ex2, .ex3 {
display: inline-block;
width: 150px; height: 150px;
margin: 0 20px;
}
.ex1.snake-border::after { content: none; }
.ex2.snake-border::before { content: none; }
/* snake-border stuff: */
@keyframes snake-border-head {
/*
The snake's "head" stretches across a side of its container.
The moment this head hits a corner, it instantly begins to
stretch across the next side. (This is why some keyframe
moments are repeated, to create these instantaneous jumps)
*/
90% { left: 0; top: 0; width: 0; height: 40%; }
90% { left: 0; top: 0; width: 0; height: 0; }
100% { left: 0; top: 0; width: 40%; height: 0; } 0% { left: 0; top: 0; width: 40%; height: 0; }
15% { left: 60%; top: 0; width: 40%; height: 0; }
15% { left: 100%; top: 0; width: 0; height: 0; }
25% { left: 100%; top: 0; width: 0; height: 40%; }
40% { left: 100%; top: 60%; width: 0; height: 40%; }
40% { left: 100%; top: 100%; width: 0; height: 0; }
50% { left: 60%; top: 100%; width: 40%; height: 0; }
65% { left: 0; top: 100%; width: 40%; height: 0; }
65% { left: 0; top: 100%; width: 0; height: 0; }
75% { left: 0; top: 60%; width: 0; height: 40%; }
}
@keyframes snake-border-tail {
/*
The "tail" of the snake is at full length when the head is at 0
length, and vice versa. The tail always at a 90 degree angle
from the head.
*/
90% { top: 0%; height: 40%; }
100% { left: 0; top: 0; width: 0; height: 0; } 0% { left: 0; top: 0; width: 0; height: 0; }
15% { width: 40%; }
25% { left: 100%; top: 0; width: 0; height: 0; }
40% { height: 40%; }
50% { left: 100%; top: 100%; width: 0; height: 0; }
65% { left: 0%; width: 40%; }
75% { left: 0; top: 100%; width: 0; height: 0; }
}
.snake-border {
position: relative;
box-shadow: inset 0 0 0 1px #00a0ff;
}
.snake-border::before, .snake-border::after {
content: '';
display: block;
position: absolute;
outline: 3px solid #00a0ff;
animation-duration: 6s;
animation-timing-function: linear;
animation-iteration-count: infinite;
}
.snake-border::before { animation-name: snake-border-head; }
.snake-border::after { animation-name: snake-border-tail; }
<div class="ex1 snake-border"></div>
<div class="ex2 snake-border"></div>
<div class="ex3 snake-border"></div>
Related Topics
CSS Positioning 70-30 with Inline-Block
How to Expand a Cropped Image into a Box
Using Calc() to Transition Width and Height in Ie
How to Break Lines in Urls in Stylesheet
Outlook Rendering Problem, Rendering Text Too Large
Why Does Chrome Read The Svg Circle Radius from The Style Attribute
Google Fonts Font Doesn't Load
CSS Margin Strange Behavior, Why
Change Background Colour as Page Scroll Without Jquery
How to Make Images in a CSS Grid Lay Next to Each Other and Jump to Another Row When Lacking Space
Vertically Aligning Block Element to Image
Stack CSS Transitions Using Multiple Classes Without Overriding
Chrome Does Not Re-Calculate Width When Height Changes
Ie 11 Ignores Min-Width When Using Flex Width