Select specific divs with an nth selector? - html

I have 12 divs tied to the same class but with different IDs and I want to apply a margin to specific ones, is this possible with a nth selector?
I have a rough example below (I'm using a sprite sheet in my actual project, so all the ra IDs have a background position set along with a width and height).
.tra-ra-cont {
display: flex;
flex-flow: row wrap;
justify-content: center;
}
.tra-ra-box {
line-height: 210px;
text-align: center;
margin: 3px;
}
.tra-ra-box a {
height: 210px;
width: 270px;
display: block;
font-size: 18px;
text-decoration: none;
color: black;
}
#ra1,
#ra2,
#ra3,
#ra4,
#ra5,
#ra6,
#ra7,
#ra8,
#ra9,
#ra10,
#ra11,
#ra12 {
background-repeat: no-repeat;
background-color: lightblue;
width: 270px;
height: 210px;
}
<div class="tra-ra-cont">
<div class="tra-ra-box" id="ra1">Range 1</div>
<div class="tra-ra-box" id="ra2">Range 2</div>
<div class="tra-ra-box" id="ra3">Range 3</div>
<div class="tra-ra-box" id="ra4">Range 4</div>
<div class="tra-ra-box" id="ra5">Range 5</div>
<div class="tra-ra-box" id="ra6">Range 6</div>
<div class="tra-ra-box" id="ra7">Range 7</div>
<div class="tra-ra-box" id="ra8">Range 8</div>
<div class="tra-ra-box" id="ra9">Range 9</div>
<div class="tra-ra-box" id="ra10">Range 10</div>
<div class="tra-ra-box" id="ra11">Range 11</div>
<div class="tra-ra-box" id="ra12">Range 12</div>
</div>
I need to apply margins to these IDs: ra2, ra3, ra6, ra7, ra10 and ra11

You can use nth-child 4n+2 (ra2, ra6 and ra10) and 4n+3 (ra3, ra7 and ra11):
.tra-ra-cont {
display: flex;
flex-flow: row wrap;
justify-content: center;
}
.tra-ra-box {
line-height: 210px;
text-align: center;
margin: 3px;
}
.tra-ra-box a {
height: 210px;
width: 270px;
display: block;
font-size: 18px;
text-decoration: none;
color: black;
}
.tra-ra-box {
background-repeat: no-repeat;
background-color: lightblue;
width: 270px;
height: 210px;
}
.tra-ra-cont > div:nth-child(4n + 2),
.tra-ra-cont > div:nth-child(4n + 3) {
background-color:red;
}
<div class="tra-ra-cont">
<div class="tra-ra-box" id="ra1">Range 1</div>
<div class="tra-ra-box" id="ra2">Range 2</div>
<div class="tra-ra-box" id="ra3">Range 3</div>
<div class="tra-ra-box" id="ra4">Range 4</div>
<div class="tra-ra-box" id="ra5">Range 5</div>
<div class="tra-ra-box" id="ra6">Range 6</div>
<div class="tra-ra-box" id="ra7">Range 7</div>
<div class="tra-ra-box" id="ra8">Range 8</div>
<div class="tra-ra-box" id="ra9">Range 9</div>
<div class="tra-ra-box" id="ra10">Range 10</div>
<div class="tra-ra-box" id="ra11">Range 11</div>
<div class="tra-ra-box" id="ra12">Range 12</div>
</div>

Related

Why isn't row-gap working on the left grid?

I have two separate one-column grids side by side. The html layout is the same for both grids but in css the grid on the left is not showing row-gap on the webpage.
html:
<div class="both-grids">
<div class="show-grid-container">
<div class="grid-item">show 1</div>
<div class="grid-item">show 2</div>
<div class="grid-item">show 3</div>
<div class="grid-item">show 4</div>
<div class="grid-item">show 5</div>
</div>
<div class="movie-grid-container">
<div class="grid-item">movie 1</div>
<div class="grid-item">movie 2</div>
<div class="grid-item">movie 3</div>
<div class="grid-item">movie 4</div>
<div class="grid-item">movie 5</div>
</div>
</div>
css:
.both-grids {
padding-left: 100px;
}
.show-grid-container, .movie-grid-container {
display: inline-grid;
grid-template-rows: 40px 200px 200px 200px 200px;
row-gap: 40px;
}
.movie-grid-container {
padding-left: 80px;
}
.show-grid-container, .movie-grid-container > div {
background-color: black;
padding-right: 80px;
padding-left: 80px;
}
You are missing > div on .show-grid-container in the last piece of CSS
.both-grids {
padding-left: 100px;
}
.show-grid-container, .movie-grid-container {
display: inline-grid;
grid-template-rows: 40px 200px 200px 200px 200px;
row-gap: 40px;
}
.movie-grid-container {
padding-left: 80px;
}
.show-grid-container >div, .movie-grid-container >div {
background-color: black;
padding-right: 80px;
padding-left: 80px;
color:white;
}
<div class="both-grids">
<div class="show-grid-container">
<div class="grid-item">show 1</div>
<div class="grid-item">show 2</div>
<div class="grid-item">show 3</div>
<div class="grid-item">show 4</div>
<div class="grid-item">show 5</div>
</div>
<div class="movie-grid-container">
<div class="grid-item">movie 1</div>
<div class="grid-item">movie 2</div>
<div class="grid-item">movie 3</div>
<div class="grid-item">movie 4</div>
<div class="grid-item">movie 5</div>
</div>
</div>
Use this in css
.show-grid-container >div, .movie-grid-container >div {}
instead of
yours -> .show-grid-container, .movie-grid-container > div {}

CSS position: sticky not working inside a wrapper element

I'm trying CSS position: sticky property, it works in a simple parent and child structure. But, when I'm trying to implement it in a more complex parent and child HTML structure, it doesn't work as expected.
In example below, I want to make <div class="ribbon"> as sticky element with a parent div as sticky container named <div classs="element">, and its grandparent named <div class="viewport"> acts as the scrollable viewport. It should stick on the left: 0 whenever I scroll the viewport scrollbar, but it doesn't.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
white-space: nowrap;
}
html, body {
font-size: 14px;
}
div {
position: relative;
display: block;
}
.container {
display: inline-block;
}
.container > .viewport {
overflow: scroll;
}
.container > .viewport > .content {
padding: 1em;
}
.container > .viewport > .content > .element {
margin-bottom: 1em;
}
.ribbon {
position: -webkit-sticky;
position: sticky;
left: 0;
padding: .5em;
background-color: bisque;
}
.ribbon .item {
display: inline-block;
margin-right: .5em;
padding: .5em;
background-color: aqua;
}
.grid {
padding: .5em;
background-color: brown;
}
<div class="container" style="width: 40em">
<div class="viewport">
<div class="content">
<div class="element">
<div class="container ribbon" style="width: 50em">
<div class="viewport">
<div class="content">
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item">Item 3</div>
<div class="item">Item 4</div>
<div class="item">Item 5</div>
<div class="item">Item 6</div>
<div class="item">Item 7</div>
<div class="item">Item 8</div>
<div class="item">Item 9</div>
<div class="item">Item 10</div>
<div class="item">Item 11</div>
<div class="item">Item 12</div>
<div class="item">Item 13</div>
</div>
</div>
</div>
</div>
<div class="element">
<div class="grid">
<div class="content">
<h4>Grid content</h4>
<h4>Grid content</h4>
<h4>Grid content</h4>
<h4>Grid content</h4>
<h4>Grid content</h4>
<h4>Grid content</h4>
</div>
</div>
</div>
</div>
</div>
</div>
Is there anything wrong with this?

Trello alike CSS layout

I'm trying to accomplish a layout similar to Trello:
kanban is always fully visible.
lane shrinks to fit the cardList.
cardList overflows when it reaches the bottom of kanban
kanban overflows horizontally when lanes are out of sight.
I'm not sure how to overflow the cardList component. I know it currently doesn't work because of the height: 100% property within .cardList, but I'd like to not have to give it a fixed height.
Also, I can't seem to overflow the kanban horizontally when I add overflow-x: scroll to .kanban.
Here's also a codesandbox in case it's easier.
:root {
--padding-card: 4px;
}
.App {
font-family: sans-serif;
text-align: center;
}
.container {
height: 90vh;
}
.kanbanWrapper {
background: black;
height: 100%;
overflow: hidden;
}
.kanban {
display: inline-flex;
background: lightgrey;
border-radius: 4px;
padding: 1rem;
margin: 1rem;
}
.kanban .lane {
margin: 0 var(--padding-card);
}
.lane {
height: 100%;
display: flex;
flex-direction: column;
background: lightpink;
width: 200px;
overflow: auto;
}
.laneHeader {
font-weight: bold;
border: 1px solid black;
padding: 0.5rem 0;
}
.laneFooter {
font-weight: bold;
border: 1px solid green;
}
.cardList {
padding: 4px;
min-height: 150px;
display: flex;
flex-direction: column;
height: 100%;
overflow: auto;
border: 1px solid blue;
}
.cardList .card {
margin: var(--padding-card);
}
.card {
background: lightgreen;
border-radius: 4px;
padding: 1rem 2rem;
}
<div class="App container">
<div class="kanbanWrapper">
<div class="kanban">
<div class="lane">
<div class="laneHeader">To do</div>
<div class="cardList">
<div class="card">Card 1 Longer title...</div>
<div class="card">Card 2</div>
<div class="card">Card 3</div>
<div class="card">Card 4</div>
<div class="card">Card 5</div>
<div class="card">Card 6</div>
<div class="card">Card 7</div>
<div class="card">Card 8</div>
<div class="card">Card 9</div>
<div class="card">Card 10</div>
<div class="card">Card 11</div>
<div class="card">Card 12</div>
</div>
<div class="laneFooter">+ Add card</div>
</div>
<div class="lane">
<div class="laneHeader">Doing</div>
<div class="cardList">
<div class="card">Card 11</div>
<div class="card">Card 12</div>
<div class="card">Card 13</div>
<div class="card">Card 14</div>
<div class="card">Card 15</div>
<div class="card">Card 16</div>
<div class="card">Card 17</div>
</div>
<div class="laneFooter">+ Add card</div>
</div>
<div class="lane">
<div class="laneHeader">Done</div>
<div class="cardList">
<div class="card">Card 21</div>
<div class="card">Card 22</div>
</div>
<div class="laneFooter">+ Add card</div>
</div>
<div class="lane">
<div class="laneHeader">Quality</div>
<div class="cardList"></div>
<div class="laneFooter">+ Add card</div>
</div>
</div>
</div>
</div>

Switch between horizontal and vertical layout using CSS (Flex or CSS Grid)

I have a table which looks by default as follows (up to 20 categories with up to 30 items for each category; each of the items will be represented by a card):
Now I'd like to give the user the option to switch to a Horizontal Layout, which should look as follows.
I have started with a JSFiddle: https://jsfiddle.net/stefanwalther/1uzh836j/15/
.status-container {
}
.row {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.col {
display: flex;
flex-direction: column;
flex: 1;
border-width: 1px;
border-style: solid;
border-color: #ccc;
padding: 3px;
}
.header {
background-color: #ccc;
}
<div>
<div class="row header">
<div class="col">
Category 1
</div>
<div class="col">
Category 2
</div>
<div class="col">
Category 3
</div>
</div>
<div class="row">
<div class="col">
Item 1.1
</div>
<div class="col">
Item 2.1
</div>
<div class="col">
Item 3.1
</div>
</div>
<div class="row">
<div class="col">
Item 1.2
</div>
<div class="col">
Item 2.2
</div>
<div class="col">
Item 3.2
</div>
</div>
</div>
Unfortunately, I am stuck, don't know which approach to chose (CSS-Grid, Flex-Box, ?).
Pure CSS flex solution is here. Supports any number of items per category.
See the snippet below:
* {
box-sizing: border-box;
font: normal 400 100%/1.25 sans-serif;
}
#switch {
display: none
}
label {
display: inline-block;
margin: 1rem;
padding: .25em .5em;
border: solid 1px;
border-radius: 1em;
}
label:after {
content: 'vertical mode';
}
#switch:checked+label:after {
content: 'horizontal mode';
}
.category {
position: relative;
display: flex;
flex-wrap: wrap;
align-items: flex-start;
padding-left: 25%
}
.category > div {
width: 25%;
padding: .5em;
border: solid 2px rgba(0, 0, 0, 0);
border-width: 0 4px 4px 0;
box-shadow: inset 0 0 0 2px #248;
text-align: center;
}
.category .header {
position: absolute;
left: 0;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
color: #fff;
background: #27c padding-box;
box-shadow: none;
}
#switch:checked ~ section {
display: flex;
justify-content: stretch;
align-items: flex-start;
width: 100%;
}
#switch:checked ~ section .category {
flex-flow: column nowrap;
width: 25%;
padding: 0;
}
#switch:checked ~ section .category > div {
width: 100%
}
#switch:checked~section .category .header {
position: static;
height: auto;
}
<input type="checkbox" id="switch"><label for="switch">Switch to </label>
<section>
<div class="category">
<div class="header">Category 1</div>
<div>Item 1.1</div>
<div>Item 1.2</div>
<div>Item 1.3</div>
<div>Item 1.4</div>
<div>Item 1.5</div>
<div>Item 1.6</div>
<div>Item 1.7</div>
<div>Item 1.8</div>
</div>
<div class="category">
<div class="header">Category 2</div>
<div>Item 2.1</div>
<div>Item 2.2</div>
<div>Item 2.3</div>
</div>
<div class="category">
<div class="header">Category 3</div>
<div>Item 3.1</div>
<div>Item 3.2</div>
<div>Item 3.3</div>
<div>Item 3.4</div>
<div>Item 3.5</div>
<div>Item 3.6</div>
<div>Item 3.7</div>
<div>Item 3.8</div>
<div>Item 3.9</div>
<div>Item 3.10</div>
<div>Item 3.11</div>
<div>Item 3.12</div>
<div>Item 3.13</div>
<div>Item 3.14</div>
</div>
<div class="category">
<div class="header">Category 4</div>
<div>Item 4.1</div>
<div>Item 4.2</div>
<div>Item 4.3</div>
<div>Item 4.4</div>
</div>
</section>

CSS Modal Scrolling

Please see the following Plunk: https://plnkr.co/edit/se1lRiXuQ4JtvqQcEtOA
I'm trying to create a modal suitable for a mobile application. Without changing the ordering of the HTML I need the CSS to achieve the following:
Fix the Header at the top (always visible) when scrolling
Keep the Buttons fixed underneath the header (always visible)
Make the Item list scrollable
As the heights of the elements may vary I'd like to be able to do this generically. So that the heights are automatically calculated
I'm stumped, any ideas?
HTML
<div class="modal">
<div class="modal-title">
Header
</div>
<div class="modal-content">
<div class="button-group">
<div class="button selected">Button One</div>
<div class="button">Button Two</div>
</div>
<div class="list"></div>
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item">Item 3</div>
<div class="item">Item 4</div>
<div class="item">Item 5</div>
<div class="item">Item 6</div>
<div class="item">Item 7</div>
<div class="item">Item 8</div>
<div class="item">Item 9</div>
<div class="item">Item 10</div>
<div class="item">Item 11</div>
<div class="item">Item 12</div>
<div class="item">Item 13</div>
<div class="item">Item 14</div>
<div class="item">Item 15</div>
<div class="item">Item 16</div>
<div class="item">Item 17</div>
<div class="item">Item 18</div>
<div class="item">Item 19</div>
<div class="item">Item 20</div>
<div class="item">Item 21</div>
<div class="item">Item 22</div>
<div class="item">Item 23</div>
<div class="item">Item 24</div>
<div class="item">Item 25</div>
<div class="item">Item 26</div>
<div class="item">Item 27</div>
<div class="item">Item 28</div>
<div class="item">Item 29</div>
<div class="item">Item 30</div>
<div class="item">Item 31</div>
<div class="item">Item 32</div>
<div class="item">Item 33</div>
<div class="item">Item 34</div>
<div class="item">Item 35</div>
<div class="item">Item 36</div>
<div class="item">Item 37</div>
<div class="item">Item 38</div>
<div class="item">Item 39</div>
<div class="item">Item 40</div>
</div>
</div>
CSS
body {
margin: 0;
}
.modal {
position: absolute;
height: 100%;
width: 100%;
background: #e9f0f6;
overflow: hidden;
}
.modal-title {
background: #FF5722;
height: 52px;
text-align: center;
color: white;
font-size: 1.40em;
line-height: 52px;
}
.modal-content {
height: auto;
}
.button-group {
display: flex;
}
.button.selected {
background: #03A9F4;
color: white;
}
.button {
flex: 1;
background: #2196F3;
color: white;
height: 26px;
text-align: center;
line-height: 26px;
cursor: pointer;
}
.list {
overflow-y: scroll;
height: 100%;
}
.item {
text-align: center;
font-size: 1.40em;
padding: 10px;
}
Add the following changes to your CSS:
1. First, make your title position: fixed;, and give it a width: 100%.
.modal-title {
position: fixed;
width: 100%;
}
2. Do the same with the title, and add a top: 52px; so it won't be behind your title.
.button-group {
top: 52px;
position: fixed;
width: 100%;
}
3. To make the list scrollable, remove the position: absolute; from your .modal class, then add some margin so your list isn't hidden behind your header and buttons.
.modal {
position: absolute; //<--- Remove this
}
.modal-content {
margin-top: 78px;
}
JSFiddle
As for the dynamic height issue, you cannot do that with CSS alone. Refer to this JavaScript solution if you'd like the buttons or title to change heights.
.modal-title{
position: fixed;
top: 0;
bottom: 0;
width: 100%;
}
.button-group{
position: fixed;
top: 52px;
width: 100%;
}
.modal{
overflow: auto;
}
now some items are hidden behind the header. Fix:
.modal-content {
margin-top: 78px;
}
EDIT: Oh Hunter was faster, sorry