Creating Check Pattern with nth-child - css

I'm trying to make a checkerboard pattern using nth-child, but it isn't working the way I expected it to.
In the example below, I want to set every other p at opposite sides of the div to create a checkerboard pattern. The p are set to width:50%;, and the div is set at width:100%.
I've set up a jsfiddle to demonstrate:
HTML
<div id='check'>
<p>Odd</p>
</div>
<div id='check'>
<p>Even</p>
</div>
CSS
#check {
float:left;
width: 100%;
}
#check p {
width: 50%;
background: #DDD;
}
#check p:nth-child(odd) {
float:right;
}
Can someone make me see how to make this work?

You need to keep all the p elements together in a single div, as the nth-child is based off the parent container. Here is a modified fiddle.. It uses this code:
HTML
<div id ='check'>
<p>Odd</p>
<p>Even</p>
<p>Odd</p>
<p>Even</p>
</div>
CSS
#check {
float:left;
width: 100%;
}
#check p {
width: 50%;
background: #DDD;
clear:both;
}
#check p:nth-child(odd) {
float:right;
}
#check p:nth-child(even) {
float:left
}

Can't have 2 elements using the same id. I believe you want to switch to using classes.
Created a fiddle to demonstrate http://jsfiddle.net/wE6e4/
#checkerboard {
width: 500px;
}
.check {
float:left;
width: 100px;
height: 100px;
}
.check:nth-child(odd) {
background: #DDD;
}
.check:nth-child(even) {
background: #fff;
}

First, you're using an ID multiple times - ID's should be unique. Besides that, the line
#check p:nth-child(odd) means that you want to set the given rules for every odd p child of #check, which is not what you want. You want to make every odd .check (I took the liberty to change the ID's to a class). So you should put them in a container and say:
#cont .check:nth-child(odd) {
float:right;
}
Here's the fiddle:
http://jsfiddle.net/Wbnks/

If you're trying to minimize your CSS, you can try something like this:
HTML:
<div class="checkerboard">
<p>1</p>
<p>2</p>
<p>3</p>
<p>4</p>
<p>5</p>
<p>6</p>
<p>7</p>
<p>8</p>
<p>9</p>
<p>10</p>
</div>
CSS:
.checkerboard p {
float: left;
width: 50%;
}
.checkerboard p:nth-child(4n-2), .checkerboard p:nth-child(4n-1) {
background-color: #999;
}
http://jsfiddle.net/L9ng7/5/

Related

How to add different CSS style to every nth element, depending on n using LESS

I am trying to add different padding to subsequent elements in a div. My DOM looks pretty simple.
<div class="parent">
<div>0</div>
<div>15</div>
<div>30</div>
...
</div>
So I would like for my first element to have 0 padding, my second 15, third 30 etc.
Using LESS, how could I make this work?
I have tried:
.parent div:nth-of-type(n) {
padding-left: n*15px;
}
Thank you!
I suppose you want to achieve a stair visually. In this case you can do it like below:
.parent {
line-height: 1.2em;
}
.parent>div:not(:first-child)::before {
content: "";
float: left;
width: 15px; /*your padding*/
height: calc(1.2em + 2px);
}
<div class="parent">
<div>0</div>
<div>15</div>
<div>30</div>
<div>45</div>
<div>60</div>
<div>75</div>
</div>
Using less(but you have to set the num of elements):
.parent (#indexstart,#index) when (#indexstart < #index ){
div:nth-child(#{indexstart}){
padding-left: (#indexstart - 1) * 15px;
}
.parent (#indexstart + 1,#index);
}
.parent (1,4);
See example

nth-last-child or last-child not working [duplicate]

I want to select the first and the last child with CSS but it does not work. Please take a look at my Fiddle and help me:
.area {
height: 100px;
width: 100px;
}
.area:first-child {
background-color: red;
}
.area:last-child {
background-color: green;
}
<div class="area">1</div>
<div class="area">2</div>
<div class="area">3</div>
<div class="area">4</div>
https://jsfiddle.net/rbw8dpsb/1/
I advise you to add a container as in your code they are childs of body BUT you don't know the last-child or the first-child of body as you may have other elements like script tags or other tags dynamically added (like in the snippet here or with jsfiddle or any other online coding tools).
.area {
height: 100px;
width: 100px;
}
.area:first-child {
background-color: red;
}
.area:last-child {
background-color: green;
}
<div>
<div class="area">1</div>
<div class="area">2</div>
<div class="area">3</div>
<div class="area">4</div>
</div>
Here is a screenshot to show what is inside your body when you run the snippet:
As you may clearly notice, there is a div added at the end which is the last-child of the body. Adding a container will avoid you dealing with random settings and hidden elements added.
If you don't want to let all that divs in another structure you should use first-of-type and last-of-type instead of first-child and last-child
.area {
height: 100px;
width: 100px;
}
.area:first-of-type {
background-color: red;
}
.area:last-of-type {
background-color: green;
}
<div class="area">1</div>
<div class="area">2</div>
<div class="area">3</div>
<div class="area">4</div>
As Temani Afif pointed, this solution is arbitrary and may not work in all the situations. As shown, it is not properly working on the code snippet but it does on JSFiddle for example. I.E. https://jsfiddle.net/vm1scerv/

Select only direct children from element with Sass

Lets say I have the following html:
<header class="header">
<div class="title">
<h1>Home</h1>
</div>
<div class="logo">
<img src="#" alt="Logo">
</div>
<div class="account">
<div class="options">
</div>
<div class="search">
</div>
</div>
</header>
And I have the following SCSS:
header {
height: 4.1rem;
div {
width: 33%;
float: left;
height: 4.1rem;
line-height: 4.1rem;
color: #fff;
&.title {
h1 {
font-weight: normal;
font-size: 3rem;
padding: 0;
margin: 0;
}
}
&.logo {
text-align: center;
}
&.account {
}
}
}
Now the problem that I have is that divs options and search are 33% percent of account which is logic as I have div {width: 33%}. I know I can select direct child elements with:
header {
> div {
}
}
But this doesn't help even if I put the > infront of all other classes. I also know I can say that the width should be 0 or what ever again in .account but I would like to prevent this.
Try this:
...
& > div {width: 33%;}
div {
float: left;
height: 4.1rem;
line-height: 4.1rem;
color: #fff;
...
Take out div width and apply it only on direct children. Leave rest as is.
Here is quick fiddle (remove .option and .search styles later, its only for visualisation).
Please edit your question and better explain what exactly you want to achieve.
Use the & with > inside the parent element like this:
.services {
& > div {
margin-bottom: 25px;
}
}
I am not certain I understand you. But I think you want a combination of direct children and child pseudo selectors, in pure CSS:
header > div:first-child {
}
Or, for the second div:
header > div:nth-child(2) {
}
You could also use the not selector:
header > div:not(.account) {
}
to exclude any unwanted div's.

CSS grid highlighting

I am playing around with a site that has an image of a 600px by 600px grid of 9 squares in its own div. I wanted to be able to highlight each grid square on hover and I have succeeded, but I would like to know if my code could be more compact.
for instance my highlight behavior never changes, but the way I am coding it I would need to code 9 of them for each square, how can I just have one and apply it to all the grid squares?
here is the code.
#theGrid
{
margin-left: auto;
margin-right: auto;
width: 600px;
height:600px;
background-image:url("img/grid.png");
}
#square1
{
top:7px;
left:7px;
width:200px;
height:200px;
background-color:transparent;
}
#square1:hover
{
background-color: yellow;
opacity:0.2;
filter: alpha(opacity=20);
}
Thanks all.
It doesn't matter weather you use class or id or not on your solution but there is a proper way in the long run. What matters is that you can use the same style name on each square. So, it would be square and not square1, 2, 3, ect... We use class for an object that is repeated on the same page multiple time and id for an object that happens one time.
Is is a quick reference I found: http://www.htmldog.com/guides/css/intermediate/classid/
here is the code that I would start using.
You will need to use float and then use a clear:both when you are on a new row.
<div id="outterWrapper">
<div id="theGrid">
<div class="square"></div><div class="square"></div><div class="square"></div>
<div class="clear"></div>
<div class="square"></div><div class="square"></div><div class="square"></div>
<div class="clear"></div>
<div class="square"></div><div class="square"></div><div class="square"></div>
</div><!-- END THE GRID -->
</div><!-- END OUTTER WRAPPER -->
#theGrid{
margin-left: auto;
margin-right: auto;
width: 600px;
height:600px;
background-image:url("img/grid.png");
}
/*Here we use class to reference all the squares*/
.square {
margin: 7px 0 0 7px; /* play with your positioning here. Can also use padding*/
width:200px;
height:200px;
background-color:transparent;
float:left; /*This will make all the boxes move next to each other*/
}
.square:hover {
background-color: yellow;
opacity:0.2;
filter: alpha(opacity=20);
}
.clear {
clear:both;
}
Instead of using # for both #square1 & #square1:hover, you could use .square1 & .square1:hover.
The # character is used for IDs ( ie. <span id="square1"></span> )
The . character is used for classes ( ie. <span class="square1"></span> )
Then apply the class ".square" to each of the nine squares. Any square with the .square class will have that style applied to it. Same goes for the hover.
Otherwise, if that doesn't work for you... you could do it in javascript by added a onmouseover and onmouseout events to each square. Then have javascript functions that handle applying the styles dynamically from code.
For example:
<div id="square1" onmouseover="handleMouseOver('square1')" onmouseout="handleMouseOut('square1')"></div>
<script>
function handleMouseOver(sq)
{
// set style
}
function handleMouseOut(sq)
{
// set style
}
</script>
You could use class instead of id
Oh, sorry I misunderstood what you want, you can just do like this
#square1:hover, #square2:hover, #square3:hover.......
{
background: yellow;
}

Any reliable, cross-browser way to distribute the remaining space in parent element between several DIVs?

Background
I am working on a browser-based UI that needs to fill the entire screen without any scrolling. The basic layout is like this:
What I want to achieve
The title div should has a fixed height (2em) and the rest 4 divs/panels should devide the remaining space of the screen according to percentages I set.
What I've tried
The best solution I've found is " CSS - How to force elements to 100% of remaining/available space of parent element without extending beyond it? ", which involves using a container div with position:absolute. This works across all browsers, but requires some additional DIVs to be created. Also, panel 2 can sometimes be forced to start on the next line due to inaccuracies in percentage widths.
My previous solution was based on CSS3 Flexbox, but the model is flawed as it does not resize child elements that have a percentage height after stretching the container boxes (at least Chrome doesn't). (The newer flex-* attributes are only implemented in Chrome and the standard is still changing.)
I have also tried the calc() function; however, it's not yet implemented in Chrome. Also, it requires hard-coding the height of the title element in two places, which I've been trying to avoid.
Edit:
What am I looking for
Just to be clear, I am not asking for a perfect/pure-CSS solution (as none seems to exist). If anyone can suggest any jQuery plug-in or open-source framework that can do this, it would be good enough for me.
In addition, I don't require any backwards compatibility with browser releases before 2012. (As long as the solution uses technology that is implemented in some browser and is going to be implemented by Firefox and Chrome in the near future, it's good enough for me.)
A little something thrown together:
http://jsfiddle.net/gDTGn/2/
Here is a pure CSS version:
http://jsfiddle.net/t0nyh0/KHzsg/63/
The trick to this technique is using position:absolute and using top, bottom, and height to create a fixed header with expanding panels. It is also really important to use:
box-sizing: border-box;
-moz-box-sizing: border-box;
to make the height and width calculations consistent across browsers. Tested and works in IE9, Firefox, and Chrome.
Pure CSS solution: http://jsfiddle.net/ehqcx/7/embedded/result/
This assumes you set width that don't sum up than more than 100%, the small gap at the right side can usually be fixed by using the same background or the background of the page. An alternative is to introduce some Javascript that sets the width of the last panel correctly, but that should be some trivial jQuery code... $("#panels .small:last").width(browser width - other small panels);
Should work correctly for the height, think away the jsFiddle header which takes away some height...
Edit:
Meh, seems the #title is bugging me... http://fiddle.jshell.net/ehqcx/7/show/light/
ECMAScript is the way to go, leaving my answer in place because of the other simplicity... :(
HTML:
<div id="content">
<div id="title">Title!</div>
<div id="panels">
<div id="panel0" class="small">0</div>
<div id="panel1" class="small">1</div>
<div id="panel2" class="small">2</div>
<div id="panel3" class="wide">3</div>
</div>
</div>​
CSS:
* { margin, padding: 0px; }
#content { background-color: black; }
#title { background-color: red; }
#panels { background-color: orange; }
#panel0 { background-color: purple; }
#panel1 { background-color: brown; }
#panel2 { background-color: orange; }
#panel3 { background-color: green; }
html, body, #content, #panels { max-height: 100%; height: 100%; max-width: 100%; width: 100%; }
#panels .small { float: left; }
#panels .wide { clear: both; }
#title { height : 2em; }
#panels .small { height: 75%; }
#panels .wide { height: 25%; }
#panel0, #panel1, #panel2 { width: 33.33%; }
It's possible using the new CSS3 flexbox model. It was basically designed to solve the problem you are facing.
Here is a simple example:
CSS:
*{margin:0 padding:0;}
html{height:100%;}
body{height:100%; display:box; box-orient:vertical;}
body > div {box-flex:1; border:1px solid black;}
.header {box-flex:0; height:4em;}
.content {
display: box;
box-orient: horizontal;
}
.content div {
box-flex: 1;
border:1px solid black;
}
HTML:
<html>
<body>
<div class="header">Title</div>
<div class="content">
<div>Panel 0</div>
<div>Panel 1</div>
<div>Panel 2</div>
</div>
<div>Panel 3</div>
</body>
</html>
It has good support in Chrome, Safari, and Firefox, with planned support in IE.
edit 2:
Tested it in
Chrome/Safari: some 1 or two pixel failure, because of percent calculations
FireFox: Perfect
IE9: Perfect
Opera: Can't have decimal places in percentage width values. This is bad
lte IE8: Does not support Array reduce function. One has to make one up (like from here: Array.reduce), Then it works at least in IE8
edit 1:
I added horizontal layout and window resize function
I've fiddled around a bit:
This is just a demonstration: To have a full fledged application you have to add the programming for the horizontal layout. But it's start
http://jsfiddle.net/HerrSerker/PmHtf/
Here is the code
HTML
<div class="full-stretch">
<div class="flex-layout flex-layout-vertical">
<div class="flex-layout-fixed" style="height:50px; text-align: center">
<div class="padding">Title</div>
</div>
<div class="flex-layout-consume flex-layout-consume-3" style="text-align: center">
<div class="flex-layout flex-layout-horizontal">
<div class="flex-layout-consume flex-layout-consume-1" style="text-align: center">
<div class="padding">Panel 0</div>
</div>
<div class="flex-layout-consume flex-layout-consume-1" style="text-align: center">
<div class="padding">Panel 1</div>
</div>
<div class="flex-layout-consume flex-layout-consume-1" style="text-align: center">
<div class="padding">Panel 2</div>
</div>
</div>
</div>
<div class="flex-layout-consume flex-layout-consume-1" style="text-align: center">
<div class="padding">Panel 3</div>
</div>
</div>
</div>​
CSS
.full-stretch {
position: absolute;
top: 2px;
right:2px;
bottom:2px;
left: 2px;
}
.padding {
position: absolute;
top: 2px;
right:2px;
bottom:2px;
left: 2px;
border: 1px solid darkGray;
background: lightBlue;
border-radius: 10px;
}
.flex-layout {
position: absolute;
top: 0;
right:0;
bottom:0;
left: 0;
overflow: hidden;
}
.flex-layout-consume {
height: 100%;
float:left;
overflow: hidden;
position: relative;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.flex-layout-vertical > .flex-layout-consume {
width: 100%;
}
.flex-layout-fixed {
height: 100%;
float:left;
overflow: hidden;
position: relative;
}
.flex-layout-vertical > .flex-layout-fixed {
width: 100%;
}
jQuery
(function($) {
var flex = function() {
$('.flex-layout').each(function() {
var fixed = $(this).children('.flex-layout-fixed');
if ($(this).hasClass('flex-layout-horizontal')) { // horizontal
var fixed_widths = $(this)
.children('.flex-layout-fixed')
.get()
.reduce(function(total, elem) {
return (total + $(elem).outerWidth())
},0)
;
var remain_width = ($(this).outerWidth() - fixed_widths)/$(this).outerWidth() * 100; // percent
var consumers = $(this)
.children('.flex-layout-consume')
.get()
;
var count_consumers = consumers
.reduce(function(total, elem) {
var cm = parseInt($(elem).attr('class').match(/flex-layout-consume-(\d+)/)[1]);
$(elem).data('consume_multiplicator', cm);
return total + cm;
},0)
;
var consumers_tic = (remain_width/count_consumers)
$(consumers).each(function() {
$(this).width(Math.round((consumers_tic * $(this).data('consume_multiplicator'))*1000)/1000+'%')
})
} else if ($(this).hasClass('flex-layout-vertical')) { // vertical
var fixed_heights = $(this)
.children('.flex-layout-fixed')
.get()
.reduce(function(total, elem) {
return (total + $(elem).outerHeight())
},0)
;
var remain_height = ($(this).outerHeight() - fixed_heights)/$(this).outerHeight() * 100; // percent
var consumers = $(this)
.children('.flex-layout-consume')
.get()
;
var count_consumers = consumers
.reduce(function(total, elem) {
var cm = parseInt($(elem).attr('class').match(/flex-layout-consume-(\d+)/)[1]);
$(elem).data('consume_multiplicator', cm);
return total + cm;
},0)
;
var consumers_tic = (remain_height/count_consumers)
$(consumers).each(function() {
$(this).height(Math.round((consumers_tic * $(this).data('consume_multiplicator'))*1000)/1000+'%')
})
}
})
};
$(function() {
flex()
$(self).resize(flex)
})
}(jQuery))
​
I might be missing something in your question, but see if this is what you are looking for. Pure CSS solution that works in all browsers down to IE7.
http://jsfiddle.net/nyHgM/1/
This is my suggestion (pure css)... Tested on IE7+, Chrome & FF http://jsfiddle.net/victmo/hKGUe/
HTML
<div id='header'></div>
<div id='col0'></div>
<div id='col1'></div>
<div id='col2'></div>
<div id='footer'></div>
CSS
div{
position:absolute;
}
#header{
top:0px;
left:0px;
right:0px;
height:3em;
}
#footer{
bottom:0px;
left:0px;
right:0px;
height:2em;
}
#col0,
#col1,
#col2{
top:3em; /* header height */
bottom:2em; /* footer height */
width:33.33%;
}
#col0{ left:0%; width:30%; } /* left = 0 */
#col1{ left:30%; width:40%; } /* left = 0 + 30 */
#col2{ left:70%; width:30%; } /* left = 30 + 40 */
/* Colors */
#header{ background:#bbb; }
#col0{ background:#ccc; }
#col1{ background:#ddd; }
#col2{ background:#eee; }
#footer{ background:#aaa; }
​

Resources