I want to change the background-color of a box after clicking on it and at the same time create another box with pure CSS. I tried it with the target selector. But I only can manage to do one of them asks and not both at the same time.
Here is a DEMO of my try.
/* fonts */
p {
font-size: 10px;
}
#school::after,
#work::after {
font-size: 10px;
content: "Second box";
color: white
}
/* white boxes */
.panel {
height: 50px;
width: 50px;
background-color: white;
border: 1px solid #262626;
position: relative;
}
/* span (100%, 100%) inside the white-boxes */
.panel span {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
}
/* second-box */
.panel div {
display: none;
}
/* if white-box is targeted, this lets the second-box appear */
.panel div:target {
display: block;
height: 50px;
width: 50px;
background-color: blue;
border: 1px solid black;
border-radius: 4px;
position: absolute;
left: 70px;
}
/* for testing purposes */
.panel:active span {
background-color: black;
}
<p>White Boxes</p>
<div class="panel">
<a href="#school">
<span></span>
</a>
<div id="school"></div>
</div>
<div class="panel">
<a href="#work">
<span></span>
</a>
<div id="work"></div>
</div>
You can modify the presentation of any number of elements using the :target pseudo-class, so long as each one is nested within the element with the id which is :targeted:
/* fonts */
p {
font-size: 10px;
}
#school div::after, #work div::after {
font-size: 10px;
content: "Second box";
color: white
}
/* white boxes */
.panel {
height: 50px;
width: 50px;
background-color: white;
border: 1px solid #262626;
position: relative;
}
/* span (100%, 100%) inside the white-boxes */
.panel span {
position:absolute;
width:100%;
height:100%;
top:0;
left: 0;
}
/* second-box */
.panel a div {
display: none;
}
/* if white-box is targeted, this lets the second-box appear */
.panel a:target div {
display: block;
height: 50px;
width: 50px;
background-color: blue;
border: 1px solid black;
border-radius: 4px;
position: absolute;
left: 70px;
}
/* if white-box is targeted, this gives the box a blue background */
.panel a:target span {
background-color: blue;
}
/* for testing purposes */
.panel:active span {
background-color: black;
}
<p>White Boxes</p>
<div class="panel">
<a href="#school" id="school">
<span></span>
<div></div>
</a>
</div>
<div class="panel">
<a href="#work" id="work">
<span></span>
<div></div>
</a>
</div>
:target is only for one element at same time, because you can't target two anchors at same time. You need javascript or a css trick with :checked
Solution with pure css :checked
http://jsfiddle.net/KNG6n/78/
What I make:
<div class="panel">
<label>
<input type="checkbox">
<div></div>
</label>
</div>
CSS
label {
display:block;
position: relative;
width: 100%;
height: 100%;
}
label input {
visibility: hidden;
}
label input:checked + div {
display: block;
}
I see an answer was accepted already, but will post my solution if anyone else is interested.
I changed the location of the div to be before the link and added a css rule.
new code:
<p>White Boxes</p>
<div class="panel">
<div id="school"></div>
<a href="#school">
<span></span>
</a>
</div>
<div class="panel">
<div id="work"></div>
<a href="#work">
<span></span>
</a>
</div>
CSS added:
.panel div:target+a span{
background-color: black;
}
Demo:
http://jsfiddle.net/KNG6n/81/
Related
I am working on a ReactJS application and I have the following HTML code that is used in a component:
<div class="order-box">
<div class="order-header">Table #1</div>
<div class="order-list">
<div class="order-item-container ">
<span class="checkmark"></span>
<div class="order-item-name">Fish and Chips × 1</div>
</div>
<div class="order-item-container ">
<span class="checkmark"></span>
<div class="order-item-name">Teriyaki Chicken × 1</div>
</div>
<div class="order-item-container ">
<span class="checkmark"></span>
<div class="order-item-name">Satay Chicken × 2</div>
</div>
<div class="order-item-container ">
<span class="checkmark"></span>
<div class="order-item-name">Lava Cake × 2</div>
</div>
</div>
</div>
I am using Sass to style the HTML code. I have the following Sass code:
.order-box {
border: 1px solid #c3c9c8;
height: 400px;
width: 400px;
border-radius: 5px;
box-shadow: 0 10px 6px -6px #ededed;
overflow: hidden;
}
.order-list {
overflow-y: scroll;
height: 80%;
}
.order-header {
text-align: center;
background: #222222;
color: #ffffff;
font-weight: bold;
font-size: 26px;
height: 20%;
display: flex;
justify-content: center;
align-items: center;
}
.order-item-container {
display: block;
position: relative;
padding-left: 35px;
cursor: pointer;
font-size: 22px;
user-select: none;
margin: 30px;
&.order-item-cooked {
.order-item-name {
text-decoration: line-through;
}
.checkmark {
background: #222222;
&:after {
display: block;
}
}
}
&.order-item-delivered {
.order-item-name {
text-decoration: line-through;
}
.checkmark {
background: #222222;
&:after {
display: block;
}
}
}
&:hover:not(.order-item-cooked) .checkmark {
background-color: #ccc;
}
&:hover:not(.order-item-delivered) .checkmark {
background-color: #ccc;
}
}
.checkmark {
position: absolute;
top: 2px;
left: 0;
height: 25px;
width: 25px;
border-radius: 15px;
background-color: #eee;
&:after {
content: "";
position: absolute;
display: none;
left: 9px;
top: 5px;
width: 5px;
height: 10px;
border: solid white;
border-width: 0 3px 3px 0;
transform: rotate(45deg);
}
}
In my React code, depending on certain conditions, the classes "order-item-cooked" and "order-item-delivered" are added to the div with the class "order-item-container".
E.g. You can have either of the following:
<div class="order-item-container order-item-cooked">
<div class="order-item-container order-item-delivered">
When the div with the order-item-container class also has the "order-item-cooked" or the "order-item-delivered" class, if one hovers over the checkmark defined by the span tag inside that div, the background colour should not change to #ccc.
The following Sass code deals with this:
&:hover:not(.order-item-cooked) .checkmark {
background-color: #ccc;
}
&:hover:not(.order-item-delivered) .checkmark {
background-color: #ccc;
}
With the above in my Sass file, when I hover over a checkmark that is within a div that has either the order-item-cooked or the order-item-delivered class, the background colour changes to #ccc.
I am not sure why this is occurring. Any insights are appreciated.
You have to chain both the not() pseudoclasses into a single selector if you want them to operate like a logical and :
&:hover:not(.order-item-cooked):not(.order-item-delivered) .checkmark {
background-color: #ccc;
}
Is it possible to achieve something like above image?
So far I have tried following Code.
.greyParent {
height: 19px;
border-radius: 7px;
background: rgb(196, 196, 196);
}
.greyParent > .activeSlide {
background: rgb(0, 97, 188);
border-radius: 7px;
border-right: 1px solid #fff;
float: left;
width: 20%;
height: 19px;
position: absolute;
}
.greyParent > .activeSlide:first-child {
left: 0%;
z-index: 5;
}
.greyParent > .activeSlide + .activeSlide {
left: 16%;
z-index: 4;
}
<div class="col-xs-4 col-sm-2 col-md-2">
<span class="slideNo">1/5</span>
</div>
<div class="col-xs-8 col-sm-10 col-xs-9 progressImage">
<div class="greyParent">
<div class="activeSlide">
</div>
<div class="activeSlide">
</div>
</div>
</div>
I need to append .activeSlide div tag depending upon tab. Problem I am facing is as I append 5 .activeSlide div tags for fifth slide its not occupying entire parent div tag i.e div.greyParent. I understand that since i am doing position absolute and trying to move divs towards right, This is happening. But since i need to highlight the border of each partition i had to use position absolute. Can someone help me on this? Is there any solution for this?
You can use :before and :after pseudo elements to create this shape.
Draw circle of equal width and height on left/right corners of each list item respectively.
Add box-shadow of 1px or 2px to create border-effect between cells.
Output Image:
* {box-sizing: border-box;}
ul {
display: flex;
list-style: none;
padding: 0;
margin: 20px;
}
ul li {
position: relative;
background: gray;
height: 16px;
width: 60px;
}
ul li:before,
ul li:after {
box-shadow: 2px 0 0 #fff;
border-radius: 100%;
position: absolute;
background: gray;
height: 16px;
content: '';
width: 16px;
left: -8px;
top: 0;
}
ul li:first-child:before {
box-shadow: none;
}
ul li:after {
right: -8px;
left: auto;
}
ul li.active,
ul li.active:before,
ul li.active:after {
background: blue;
z-index: 1;
}
<ul>
<li class="active"></li>
<li class="active"></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
You can simply overlap the elements and give them the right width to make sure that they will be in the right place. You should also play with the left property to make them appear where you want.
The key should be in the properties you can see here:
.greyParent > div{
width: 25%;
}
.greyParent > div:nth-child(1){
left:0%;
width: 20%;
}
.greyParent > div:nth-child(2){
left:15%;
}
I have created this small jsfiddle which you can see as an example of what I mean
Try this, it's good ))
<div class="container">
<div class="title">
1/5
</div>
<div class="progress">
<span class="active"></span><span class="active"></span><span></span><span></span><span></span>
</div>
</div>
.container {
display: flex;
}
.container .title {
padding-right: 20px;
}
.container .progress {
display: flex;
width: 250px;
}
.container .progress span {
display: block;
height: 15px;
width: 20%;
background: gray;
border: solid 1px #fff;
border-radius: 7px;
margin-right: -15px;
}
.container .progress span.active {
background: blue;
}
.container .progress span:nth-child(1) {
z-index: 40;
}
.container .progress span:nth-child(2) {
z-index: 35;
}
.container .progress span:nth-child(3) {
z-index: 25;
}
.container .progress span:nth-child(4) {
z-index: 10;
}
JSfiddle example https://jsfiddle.net/5ph3uk94/
Why don't you just use 2 blue elements and 3 grey elements, instead of one big grey parent ?
<div class="col-xs-4 col-sm-2 col-md-2">
<span class="slideNo">1/5</span>
</div>
<div class="col-xs-8 col-sm-10 col-xs-9 progressImage">
<div class="parent">
<div class="activeSlide"></div>
<div class="activeSlide"></div>
<div class="diabledSlide"></div>
<div class="diabledSlide"></div>
<div class="diabledSlide"></div>
</div>
</div>
Here is the outcome
What I want to achieve are
A gray circle surrounding the '<' with the letter in the center
It and 'untitled' aligns vertically to the center
However despite setting the width and height to the same size, the 'circle' still ends up in an oval shape.
The use of flex's align-items: center; also fails to achieve the alignment.
How can I fix the css? Here is a link to the sample code
html
<div class='flex-container'>
<div class='arrow-container'>
<a class='btn-icon' href='#'>
<span class='square-btn icon icon-back'></span>
</a>
</div>
<div class=title>
<a href='#'>Untitled
</a>
</div>
</div>
css
.flex-container {
display: flex;
align-items: center;
}
.icon {
font-size: 50px;
}
.icon-back::before {
content: '<';
}
.title {
margin-left: 5px;
font-size: 50px;
}
.square-btn {
height: 50px;
width: 50px;
}
.btn-icon {
padding: 5px;
border-radius: 50%;
background-color: gray;
text-decoration: none;
}
This seems to work. No changes to HTML.
.flex-container {
display: flex;
align-items: center;
}
.icon {
font-size: 50px;
}
.icon-back::before {
content: '<';
}
.title {
margin-left: 5px;
font-size: 50px;
}
.square-btn {
height: 50px;
width: 50px;
border-radius: 50%; /* new */
background-color: gray; /* new */
display: flex; /* new */
align-items: center; /* new; align arrow vertically */
justify-content: center; /* new; align arrow horizontally */
}
.btn-icon {
/* padding: 5px; <-- remove */
/* border-radius: 50%; <-- remove */
/* background-color: gray; <-- remove */
text-decoration: none;
}
<div class='flex-container'>
<div class='arrow-container'>
<a class='btn-icon' href='#'>
<span class='square-btn icon icon-back'></span>
</a>
</div>
<div class=title>
<a href='#'>Untitled
</a>
</div>
</div>
jsFiddle
This can be done with a single html element and pseude-elements. One neat advantage of making everything depend on the font-size is, that the icon scales proportionally with the font size of the link.
.link {
font-size: 50px;
margin-left: 1.1em;
}
.icon {
position: relative;
}
.icon-back::before {
content: '<';
position: absolute;
left: -.9em;
display: inline-block;
z-index: 2;
}
.icon-back::after {
content: '';
border-radius: 50%;
background-color: gray;
width: 1em;
height: 1em;
position: absolute;
top: 50%;
left: -1.1em;
/* Use translateX() and translateY()
if you care about old browsers */
transform: translate3d(0, -45%, 0);
}
<a class="link icon icon-back" href="#">Untitled</a>
Grouping classes makes things harder, also, use unicode in css content when it's not alpha-numerical text, try this:
<div class="flex-container">
<div class="arrow-container">
<a class="btn-icon" href="#">
<span class="icon-back"></span>
</a>
</div>
<div class="title">
<a href="#">Untitled
</a>
</div>
</div>
<style type="text/css">
.flex-container {
display: flex;
align-items: center;
}
.btn-icon {
font-size: 50px;
text-decoration: none;
}
.icon-back::before {
content: "\003c";
border-radius: 50%;
background-color: gray;
font-size: 40px;
height:40px;
width:40px;
vertical-align:middle;
display:inline-block;
margin-bottom:5px;
text-align:center;
}
.title {
margin-left: 5px;
font-size: 50px;
}
</style>
I have a div and inside this div there is an icon with background and text.
when clicking on this div I want to change 3 things:
the div background, the icon background and the text color.
how can I do it with CSS only?
http://jsfiddle.net/g1nrye8e/
<div class="click">
<div class="icon"></div>
<div class="text">text</div>
</div>
.click{
width: 200px;
height: 100px;
background: blue;
}
.icon{
width: 50px;
height:50px;
background: yellow;
display: inline-block;
}
.text{
color: #fff;
display: inline-block;
}
Preserve clicked state using pure CSS
The best way to preserve the clicked state, without JavaScript is to
wrap your elements inside a <label>
immediately before the element you want to target place an invisible input checkbox
when the input becomes :checked target any first next sibling element using +* and change styles accordingly
Repeat the same rule for +*'s inner elements:
/* DEFAULT STYLES */
.div{
width: 200px;
height: 100px;
background: blue;
margin:10px;
}
.icon{
width: 50px;
height:50px;
background: yellow;
display: inline-block;
}
.text{
color: #fff;
display: inline-block;
}
/* HIDE CHECKBOX HELPER */
label.click > input{ /* hide the input checkbox */
position:absolute;
visibility:hidden;
}
/* ACTIVE STYLES */
label.click > input:checked +* { /* (the next .div) */
background: #000;
}
label.click > input:checked +* .icon{
background: #c0ffee;
}
label.click > input:checked +* .text{
color: #f00ba4;
}
<label class="click">
<input type="checkbox"> <!-- :checked state changes +div styles -->
<div class="div">
<div class="icon"></div>
<div class="text">text</div>
</div>
</label>
<label class="click">
<input type="checkbox">
<div class="div">
<div class="icon"></div>
<div class="text">text</div>
</div>
</label>
Just add a class to the parent when it is clicked, then write more specific CS for that class.
Here's a running example.
document.querySelector(".click").addEventListener("click", function() {
this.classList.toggle("clicked");
});
.click{
width: 200px;
height: 100px;
background: blue;
}
.icon{
width: 50px;
height:50px;
background: yellow;
display: inline-block;
}
.text{
color: #fff;
display: inline-block;
}
.clicked.click{
background: green;
}
.clicked .icon{
background: red;
}
.clicked .text{
color: blue;
}
<div class="click">
<div class="icon"></div>
<div class="text">text</div>
</div>
This is a different solution with only css, but you have to click to every element:
.click{
width: 200px;
height: 100px;
background: blue;
}
.icon{
width: 50px;
height:50px;
background: yellow;
display: inline-block;
}
.text{
color: #fff;
display: inline-block;
}
.click:focus{
background: red;
}
.icon:focus{
background: grey;
}
.text:focus{
background: black;
}
<div class="click" tabindex="1">
<div class="icon" tabindex="2"></div>
<div class="text" tabindex="3">text</div>
</div>
There is a great explanations about the tabindex and :focus without using JS. Check it out impressivewebs
Here is a fiddle of the below:
.filterDivActual, #filterSeparator {
display: inline-block;
}
.filterDivActual {
border: 2px solid grey;
width: 15%;
height: 50px;
line-height: 50px;
color: grey;
position: relative;
}
#filterSeparator {
height: 50px;
width: 5px;
background-color: black;
}
<div id='filterDiv'>
<div class='filterDivActual'>Top</div>
<div class='filterDivActual'>New</div>
<div id='filterSeparator'></div>
<div class='filterDivActual'>Today</div>
<div class='filterDivActual'>Yesterday</div>
<div class='filterDivActual'>None</div>
</div>
What I want is for the #filterSeparator to be aligned with the other divs.
For some reason, all the other divs are below the #filterSeparator.
If I put text inside #filterSeparator, then it works.
Is there a way for me to get it to work without placing any text inside #filterSeparator?
fiddle
For inline / inline-block elements, use the vertical-align property:
.filterDivActual, #filterSeperator {
display: inline-block;
vertical-align: middle ; /* or some other value: */
}
https://developer.mozilla.org/en-US/docs/Web/CSS/vertical-align
I don't know why it does this but you can fix it by using float:left; instead of display:inline-block
Putting content in the empty <div> will fix it.
<div id='filterSeperator'> </div>
#filterSeparator:before {
content: ".";
visibility: hidden;
}
.filterDivActual, #filterSeparator {
display: inline-block;
}
.filterDivActual {
border: 2px solid grey;
width: 15%;
height: 50px;
color: grey;
position: relative;
}
#filterSeparator {
height: 50px;
width: 5px;
background-color: black;
}
#filterSeparator:before {
content: ".";
visibility: hidden;
}
<div id='filterDiv'>
<div class='filterDivActual'>Top</div>
<div class='filterDivActual'>New</div>
<div id='filterSeparator'></div>
<div class='filterDivActual'>Today</div>
<div class='filterDivActual'>Yesterday</div>
<div class='filterDivActual'>None</div>
</div>