Can I move an element to another element with CSS? - html

Can we swap items from different div using CSS?
I need to move item duaA to satuA and otherwise. Is it possible?
I have something like this:
<div id="satu">
<div class="satuA"></div>
<div class="satuB"></div>
</div>
<div id="dua">
<div class="duaA"></div>
<div class="duaB"></div>
</div>

.parent {
display: flex;
direction: rtl;
align-items: right;
justify-content: flex-end;
}
<div class="parent">
<div id="satu">
<div class="satuA">satuA</div>
<div class="satuB">satuB</div>
</div>
<div id="dua">
<div class="duaA">duaA</div>
<div class="duaB">duaA</div>
</div>
</div>
Do you need like that way. I have used Direction css.

I don't think it is possible to use CSS to swap physical content (if you mean that), but it is in JavaScript.
function swap() {
const satu = document.getElementById("satu").innerHTML
const dua = document.getElementById("dua").innerHTML
document.getElementById("satu").innerHTML = dua
document.getElementById("dua").innerHTML = satu
}
swap()
console.log(document.getElementById("content").innerHTML)
<div id="content">
<div id="satu">
<div class="satuA"></div>
<div class="satuB"></div>
</div>
<div id="dua">
<div class="duaA"></div>
<div class="duaB"></div>
</div>
</div>

Following my first comment, Here is a grid possibility from a common container for both parents:
Follow my second comment : Is it 2 or 4 of them to swap and then, to which position exactly? Is it a simple row, a simple column or a columns and rows layout? , if snippet below do not answer your question.
grid demos:
#satudua {
display: grid;
}
div div {
margin: 4px;
border: solid 2px;
}
#satu,
#dua {
grid-row: 1;
grid-column: 1;
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: repeat(2, 1fr)
}
.satuA {
grid-row: 2;
grid-column: 1;
color: green
}
.duaA {
grid-row: 1;
grid-column: 1;
color: tomato
}
.satuB {
grid-row: 1;
grid-column: 2;
}
.duaB {
grid-row: 2;
grid-column: 2;
}
div div div:first-of-type:before {
content: ' Swapped ';
color: black;
}
<div id="satudua">
<div id="satu">
<div class="satuA">satuA</div>
<div class="satuB">satuB</div>
</div>
<div id="dua">
<div class="duaA">duaA</div>
<div class="duaB">duaB</div>
</div>
</div>
or was it side by side ?
#satudua {
display: grid;
}
div div {
margin: 4px;
border: solid 2px;
}
#satu,
#dua {
grid-row: 1;
grid-column: 1;
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: repeat(2, 1fr)
}
#satu>div {
grid-column: 1;
grid-row: 2;
}
#dua>div {
grid-column: 2;
grid-row: 2;
}
#satu>.satuA {
grid-row: 1;
grid-column: 2;
color: green
}
#dua>.duaA {
grid-row: 1;
grid-column: 1;
color: tomato
}
div div div:first-of-type:before {
content: ' Swapped ';
color: black;
}
<div id="satudua">
<div id="satu">
<div class="satuA">satuA</div>
<div class="satuB">satuB</div>
</div>
<div id="dua">
<div class="duaA">duaA</div>
<div class="duaB">duaB</div>
</div>
</div>

Related

Align images responsive in a flower shape

I have 4 icons which should align like the image below.
I've tried to first put them into a <div> with a class which controlls the position.
Now with my knowledge I would give every each image a absolute position, but that will not work, because on every res. my images are not together and just all over the place.
How can I align my images like a "flower" in a responsive way.
For a responsive layout you can use CSS grid:
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(4, 1fr);
width: 50vw;
aspect-ratio: 3 / 2;
}
.container>div {
aspect-ratio: 1 / 1;
border: 1px solid black;
box-sizing: border-box;
}
.container>div:nth-child(1) {
grid-column: 1;
grid-row: 2 / span 2;
}
.container>div:nth-child(2) {
grid-column: 2;
grid-row: 1 / span 2;
}
.container>div:nth-child(3) {
grid-column: 3;
grid-row: 2 / span 2;
}
.container>div:nth-child(4) {
grid-column: 2;
grid-row: 3 / span 2;
}
<div class="container">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
Obviously set the container width to what you require.
This snippet sets the divs in a clockwise fashion starting at the left most div.
I have just recreated what you posted above. I can help you when you specify what you really need
.main {
display: flex;
height:100%;
align-items:center
}
.sec{
height: 50px;
width: 50px;
border:1px solid black
}
<div class="main">
<div class="sec"></div>
<div class="sec2">
<div class="sec"></div>
<div class="sec"></div>
</div>
<div class="sec"></div>
</div>
Need to create 3 columns wrapped in a flex container and aligned vertically
.wrapper {
display: flex;
}
.column {
align-items: center;
}

Make a grid as big as the screen

I need the grid ad big as the page (it should touch the top the bottom and both sides) and I'd like it to be non-scrollable.
HTML:
<div class="wrapper">
<div class="prova">One</div>
<div class="prova"> </div>
<div class="prova">Three</div>
<div class="prova">Four</div>
<div class="prova"> five </div>
<div class="prova">Six</div>
<div class="prova">Seven</div>
<div class="prova">Eight</div>
<div class="prova">Nine</div>
<div class="prova">Ten</div>
<div class="prova">Eleven</div>
<div class="prova">Twelve</div>
</div>
CSS:
.wrapper {
padding-top: 10%;
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: 100px;
}
.prova{
border: 1px solid;
}
.wrapper div:nth-child(2) {
grid-column: 3;
grid-row: 2 / 4;
}
.wrapper div:nth-child(5) {
grid-column: 1 / 3;
grid-row: 1 / 3;
}
I've read multiple questions but I couldn't find any solution that works fine for me.
As you can see in the picture above the grid doesn't touch neither the top or the bottom!
Set gird-auto-rows to use a percentage of the viewport height. Equal amounts per expected row. So in your case 25vh. Then remove any padding or margin around the grid.
html, body {
margin: 0
}
.wrapper {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: 25vh;
width: 100%;
}
.prova{
border: 1px solid;
}
.wrapper div:nth-child(2) {
grid-column: 3;
grid-row: 2 / 4;
}
.wrapper div:nth-child(5) {
grid-column: 1 / 3;
grid-row: 1 / 3;
}
<div class="wrapper">
<div class="prova">One</div>
<div class="prova"> </div>
<div class="prova">Three</div>
<div class="prova">Four</div>
<div class="prova"> five </div>
<div class="prova">Six</div>
<div class="prova">Seven</div>
<div class="prova">Eight</div>
<div class="prova">Nine</div>
<div class="prova">Ten</div>
<div class="prova">Eleven</div>
<div class="prova">Twelve</div>
</div>
If you want it to touches the top just remove the padding
And for other sides just set the width and height of the wrapper to 100vh and 100vw

Inserting a new div between two grid items

I have the following grid layout:
<div class="main-page">
<div class="side-bar"></div>
<div class="nav-bar"></div>
<div class="index-view"></div>
</div>
and I am trying to insert a new div between sidebar and index such that the resulting layout will be like:
<div class="main-page">
<div class="side-bar"></div>
<div class="nav-bar"></div>
<div class="profile-pane"></div>
<div class="index-view"></div>
</div>
My attempt so far has been:
.main-page {
display: grid;
grid-template-columns: auto 1fr;
grid-template-rows: 72px 1fr;
height: 100%;
}
.main-page > .side-bar {
display: grid;
grid-row: 1/4;
width: 80px;
}
.main-page > .profile-pane {
width: 260px;
position: relative;
grid-row: 2/4;
}
.main-page > .index-view {
grid-row: 2/4;
}
This renders a huge space between profile and index and compresses index to the right. I've been trying different values for the grid-row property but to no avail. However, if I remove either one of profile and index, the remaining div will render nicely and right beside the sidebar. How do I achieve the second layout?
You can consider different values based on the existance of the profile element:
.main-page {
display: grid;
grid-template-columns: 80px 1fr 4fr;
grid-template-rows: 72px 1fr;
height: 200px;
margin:20px;
}
.side-bar {
grid-row: span 2;
}
.nav-bar,
.index-view {
grid-column:span 2;
}
/* Take only one clumn if profile exist*/
.profile-pane + .index-view {
grid-column:span 1;
}
/* Irrelevant code */
.main-page > * {
border:1px solid;
}
.main-page > *:before {
content:attr(class);
}
<div class="main-page">
<div class="side-bar"></div>
<div class="nav-bar"></div>
<!--<div class="profile-pane"></div>-->
<div class="index-view"></div>
</div>
<div class="main-page">
<div class="side-bar"></div>
<div class="nav-bar"></div>
<div class="profile-pane"></div>
<div class="index-view"></div>
</div>
You can achieve the desired result by setting the "grid-row: span 2" property in the sidebar to increase its height by two lines. And for the navigation bar, the "grid-column: span 2" property is to expand it into two columns
Oh yes, and do not forget to set the columns of the required width for the grid container grid-template-columns: 10% 15% 70%;
Result:
.main-page {
display: grid;
grid-template-columns: 10% 15% 70%;
}
.main-page>* {
padding: 20px;
border: 1px solid #000;
}
.side-bar {
grid-row: span 2;
}
.nav-bar {
grid-column: span 2;
}
.index-view {
min-height: 500px;
}
<div class="main-page">
<div class="side-bar">side-bar</div>
<div class="nav-bar">nav-bar</div>
<div class="profile-pane">profile-pane</div>
<div class="index-view">index-view</div>
</div>

Css grid, large size on some cards, how to place them like this

I'm using grid for this layout and I'm halfway through. As you can see number 10,20,30,40,50 gets placed on the same spot (I place them there). I would like to have my layout as from 1 to 10 are
Large on the left (1,11,21,31,41...), 4 small on the right
Large on the right (10,20,30,40...), 4 small on the left
NOTE, this list can contain from 40-100 items, so using fixed positions to place it there would not be an option. Also the making nr 6 large and changing the order does not work either due to sorting.
Hope it's clear what I'm trying to do here.
.layout-scale {
display: grid;
grid-template-columns: repeat(4, 25%);
grid-gap: 1rem;
}
.layout-scale__items {
background-color: aqua;
min-height: 10rem;
}
.layout-scale__items:nth-child(10n + 1) {
background-color: deeppink;
grid-column: span 2;
grid-row: span 2;
}
.layout-scale__items:nth-child(10n + 10) {
background-color: lime;
grid-column: 3 / span 2;
grid-row: 3 / span 2;
}
<div class="layout-scale">
<div class="layout-scale__items">1</div>
<div class="layout-scale__items">2</div>
<div class="layout-scale__items">3</div>
<div class="layout-scale__items">4</div>
<div class="layout-scale__items">5</div>
<div class="layout-scale__items">6</div>
<div class="layout-scale__items">7</div>
<div class="layout-scale__items">8</div>
<div class="layout-scale__items">9</div>
<div class="layout-scale__items">10</div>
<div class="layout-scale__items">11</div>
<div class="layout-scale__items">12</div>
<div class="layout-scale__items">13</div>
<div class="layout-scale__items">14</div>
<div class="layout-scale__items">15</div>
<div class="layout-scale__items">16</div>
<div class="layout-scale__items">17</div>
<div class="layout-scale__items">18</div>
<div class="layout-scale__items">19</div>
<div class="layout-scale__items">20</div>
<div class="layout-scale__items">21</div>
<div class="layout-scale__items">22</div>
<div class="layout-scale__items">23</div>
<div class="layout-scale__items">24</div>
<div class="layout-scale__items">25</div>
<div class="layout-scale__items">26</div>
<div class="layout-scale__items">27</div>
<div class="layout-scale__items">28</div>
<div class="layout-scale__items">29</div>
<div class="layout-scale__items">30</div>
<div class="layout-scale__items">31</div>
<div class="layout-scale__items">32</div>
<div class="layout-scale__items">33</div>
<div class="layout-scale__items">34</div>
<div class="layout-scale__items">35</div>
<div class="layout-scale__items">36</div>
<div class="layout-scale__items">37</div>
<div class="layout-scale__items">38</div>
<div class="layout-scale__items">39</div>
<div class="layout-scale__items">40</div>
<div class="layout-scale__items">41</div>
<div class="layout-scale__items">42</div>
<div class="layout-scale__items">43</div>
<div class="layout-scale__items">44</div>
<div class="layout-scale__items">45</div>
<div class="layout-scale__items">46</div>
<div class="layout-scale__items">47</div>
<div class="layout-scale__items">48</div>
<div class="layout-scale__items">49</div>
<div class="layout-scale__items">50</div>
</div>
All green boxes start at 3rd row (grid-row: 3 / span 2) so they are in the same place.
Also, if I understood the pattern in your mind, you have to use indexes 1,11,21,.. and indexes 8,18,28,...
Try this:
.layout-scale {
display: grid;
grid-template-columns: repeat(4, 25%);
grid-gap: 1rem;
}
.layout-scale__items {
background-color: aqua;
min-height: 10rem;
}
.layout-scale__items:nth-child(10n + 1) {
background-color: deeppink;
grid-column: span 2;
grid-row: span 2;
}
.layout-scale__items:nth-child(10n + 8) {
background-color: lime;
grid-column: span 2;
grid-row: span 2;
}
I have landed in solving it with "fixed" position on grid-row. I have a loop in scss that generates it for the :nth-child(). The 10 extra classes are worth it compared to the extra markup and css to solve it with a "row" "bootstrap if you will" approach, and even more css for eventually that would be for a fallback solution. For my use case it will not be more than 100 items. If your case use more then 100 items just change the loop times.
$increment: 3;
// change the 10 to your wanted amount
#for $i from 1 through 10 {
.layout-scale__items:nth-child(#{$i*10}) {
grid-row: #{$increment} / span 2;
}
$increment: $increment + 4;
}
My full solution is on jsfiddle (due to internal code editor does not support scss)
<div class="layout-scale">
<div class="layout-scale__items">1</div>
<div class="layout-scale__items">2</div>
<div class="layout-scale__items">3</div>
<div class="layout-scale__items">4</div>
<div class="layout-scale__items">5</div>
<div class="layout-scale__items">6</div>
<div class="layout-scale__items">7</div>
<div class="layout-scale__items">8</div>
<div class="layout-scale__items">9</div>
<div class="layout-scale__items">10</div>
<div class="layout-scale__items">11</div>
...
</div>
.layout-scale {
display: grid;
grid-template-columns: repeat(4, 25%);
grid-gap: 1rem;
}
.layout-scale__items {
background-color: aqua;
min-height: 10rem;
}
.layout-scale__items:nth-child(10n + 1) {
background-color: deeppink;
grid-column: span 2;
grid-row: span 2;
}
.layout-scale__items:nth-child(10n + 10) {
background-color: lime;
grid-column: 3 / span 2;
}
$increment: 3;
#for $i from 1 through 10 {
.layout-scale__items:nth-child(#{$i*10}) {
grid-row: #{$increment} / span 2;
}
$increment: $increment + 4;
}

Grid item not aligning as expected

I am trying to get the content of item to be in the middle column, but it does not seem to be moving.
.home-grid-container {
display: grid;
grid-template-columns: auto;
grid-template-rows: 0.10fr 0.98fr auto;
height: 100vh;
}
.home-header {
grid-column: 1 / span 3;
grid-row: 1 / span 1;
background: #3f51b5;
}
.home-main {
grid-column: 1 / span 3;
grid-row: 2 / span 3;
background: #81d4fa;
}
.item {
grid-column: 2 / span 1;
grid-row: 2 / span 3;
}
.home-footer {
grid-column: 1 / span 3;
grid-row: 5 / span 1;
background: #3f51b5;
div {
text-align: center;
margin: 2vh;
}
}
<div class="home-grid-container">
<div class="home-header">
<h1>
<img src="/src/imgs/sitelogo.png" />
</h1>
</div>
<div class="home-main">
<div class="item">
Simple, Fast, Powerful
<input type="button" value="100% Free" />
</div>
</div>
<div class="home-footer">
<div>All Rights Reserved</div>
</div>
</div>
https://css-tricks.com/snippets/css/complete-guide-grid/
The elements you want to center are descendants, but not children, of the grid container.
Because grid layout only extends between parent and child elements, the .item element is out of scope and will not accept grid properties.
But these elements are inline-level children of a block container, which means that text-align: center will work.
.home-grid-container {
display: grid;
grid-template-columns: auto;
grid-template-rows: 0.10fr 0.98fr auto;
height: 100vh;
}
.home-header {
grid-column: 1 / span 3;
grid-row: 1 / span 1;
background: #3f51b5;
}
.home-main {
grid-column: 1 / span 3;
grid-row: 2 / span 3;
background: #81d4fa;
}
.item {
grid-column: 2 / span 1;
grid-row: 2 / span 3;
text-align: center; /* NEW */
}
.home-footer {
grid-column: 1 / span 3;
grid-row: 5 / span 1;
background: #3f51b5;
}
<div class="home-grid-container">
<div class="home-header">
<h1>
<img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt="">
</h1>
</div>
<div class="home-main">
<div class="item">
Simple, Fast, Powerful
<input type="button" value="100% Free" />
</div>
</div>
<div class="home-footer">
<div>All Rights Reserved</div>
</div>
</div>
jsFiddle demo
If you want to use the grid for a child of your container, you can always just inherit the same properties.
.home-grid-container {
display: grid;
grid-template-columns: auto;
grid-template-rows: 0.10fr 0.98fr auto;
height: 100vh;
}
.home-header {
grid-column: 1 / span 3;
grid-row: 1 / span 1;
background: #3f51b5;
}
.home-main {
grid-column: 1 / span 3;
grid-row: 2 / span 3;
background: #81d4fa;
/* inherit the container-grid setup */
display: grid;
grid-template-columns: inherit;
grid-template-rows: inherit;
}
.item {
grid-column: 2 / span 1;
grid-row: 2 / span 3;
}
.home-footer {
grid-column: 1 / span 3;
grid-row: 5 / span 1;
background: #3f51b5;
div {
text-align: center;
margin: 2vh;
}
}
<div class="home-grid-container">
<div class="home-header">
<h1>
<img src="https://dummyimage.com/200x50/cccccc/ffffff.png" />
</h1>
</div>
<div class="home-main">
<div class="item">
Simple, Fast, Powerful
<input type="button" value="100% Free" />
</div>
</div>
<div class="home-footer">
<div>All Rights Reserved</div>
</div>
</div>
As others have pointed out, since the item element isn't a direct child of the grid container - you can't apply grid properties to it.
Obviously, to fix this you could pull the item out of the home-main div and make it a direct child of the grid - but I'm guessing that that's not a viable solution here :)
Grid Layout Module Level 2 - Subgrids are supposed to solve this problem.
Subgrid is currently only a draft spec, but fwiw, in your case you would do something like:
.home-main {
display: subgrid;
grid-column: span 3;
}
Nevertheless, there actually is a way to pull this off:
display: contents (caniuse)
From Caniuse:
display: contents causes an element's children to appear as if they
were direct children of the element's parent, ignoring the element
itself. This can be useful when a wrapper element should be ignored
when using CSS grid or similar layout techniques.
So in order for the grid placement properties to work on the item, you could simply add display: contents; to home-main (currently working in Firefox)
(NB: This will obviously render the grid properties on home-main useless - but then again - they aren't necessary to place the item)
.home-main {
display: contents;
...
}
.home-grid-container {
display: grid;
grid-template-columns: auto;
grid-template-rows: 0.10fr 0.98fr auto;
height: 100vh;
}
.home-header {
grid-column: 1 / span 3;
grid-row: 1 / span 1;
background: #3f51b5;
}
.home-main {
/*grid-column: 1 / span 3;
grid-row: 2 / span 3; */
display: contents;
background: #81d4fa;
}
.item {
grid-column: 2 / span 1;
grid-row: 2 / span 3;
background: salmon;
}
.home-footer {
grid-column: 1 / span 3;
grid-row: 5 / span 1;
background: #3f51b5;
}
.home-footer div {
text-align: center;
margin: 2vh;
}
<div class="home-grid-container">
<div class="home-header">
<h1>
<img src="/src/imgs/sitelogo.png" />
</h1>
</div>
<div class="home-main">
<div class="item">
Simple, Fast, Powerful
<input type="button" value="100% Free" />
</div>
</div>
<div class="home-footer">
<div>All Rights Reserved</div>
</div>
</div>