CSS :before and sibling selector not working - css

I have the following markup, and I need to find a CSS way to change a triangle whenever .hide class is active.
To achieve this I've used a pseudo element like this:
summary:before {
content: '\25BC';
}
summary:before + .hide {
content: '\25BA';
}
The problem is: it doesn't work. The arrow doesn't change. Even though summary:before + .hide appears in the DevTools.
So how to achive the desired effect without using JavaScript only CSS?
var $div = $('summary');
$div.on('click', function() {
$('ul').toggleClass('hide');
});
.wrapper {
width: 300px;
height: 300px;
background-color: #ecf0f1;
}
.details {
outline: none;
background-color: #95a5a6;
cursor: pointer;
position: relative;
}
summary {
outline: none;
margin-left: 30px;
}
summary:before {
content: '\25BA';
font-size: 12px;
position: absolute;
top: 2px;
left: 13px;
}
summary:before + ul.hide {
content: '\25BC';
font-size: 12px;
position: absolute;
top: 2px;
left: 13px;
}
.hide {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div class="details">
<summary>Sample</summary>
<ul class="hide">
<li>
<input type="radio" checked/>
<label>Label 1</label>
</li>
<li>
<input type="radio" />
<label>Label 2</label>
</li>
<li>
<input type="radio" />
<label>Label 3</label>
</li>
</ul>
</div>
</div>

You can't select the previous element in CSS. Instead add a class to the div and toggle it.
Try below solution.
var $div = $('summary');
$div.on('click', function() {
$('ul').toggleClass('hide');
$(this).toggleClass('collapse');
});
.wrapper {
width: 300px;
height: 300px;
background-color: #ecf0f1;
}
.details {
outline: none;
background-color: #95a5a6;
cursor: pointer;
position: relative;
}
summary {
outline: none;
margin-left: 30px;
}
summary:before {
content: '\25BA';
font-size: 12px;
position: absolute;
top: 2px;
left: 13px;
}
summary.collapse:before {
content: '\25BC';
}
.hide {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div class="details">
<summary>Sample</summary>
<ul class="hide">
<li>
<input type="radio" checked/>
<label>Label 1</label>
</li>
<li>
<input type="radio" />
<label>Label 2</label>
</li>
<li>
<input type="radio" />
<label>Label 3</label>
</li>
</ul>
</div>
</div>

You have made 2 mistakes in you code writing.
1st: You have duplicated the styles for your pseudo classes in two places.
2nd: You've put the 'hidden' class directly to the sibling. The right way to do it is to put it in the parent, this way you can access all its children.
You've toggled the class 'hidden' whereas it should be 'expand', because by default, as I understand, your menu is closed and when the user clicks on the details box it ('expands'). Hope that makes sense.
I've made two codepens for you.
In the first we expand the ul list using display:block and display:none and following the class added in the jQuery.
Example 1
In the second we expand the ul list using only jquery to achieve nice slide animation. We also hide the ul by default.
Example 2

Related

Issues with CSS checkbox checked not working in nav ul

I have a checkbox like this,
<nav>
<div id="center">
<ul>
<li>Home</li>
<li>Skill</li>
<li>Profile</li>
</ul>
<input type="checkbox" id="check">
<label for="check" class="checkbtn">
<i class="fas fa-bars"></i>
</label>
</div>
</nav>
but, the check box doesn't work on the check box selector and I don't know why.
this is my css nav and check box.
nav ul{
position: fixed;
width: 100%;
height: 200px;
background: #2c3e50;
top: 47px;
display: none;
text-align: center;
padding-left: 0;
transition: all .5s;
}
#check:checked ~ nav ul {
display: block;
}
On a related note, ~ is for the general successor sibling (meaning the element comes after this one).
Since your ul has the fixed position, move it after label tag.
Also remove nav from #check:checked ~ nav ul in css style.
nav ul {
position: fixed;
width: 100%;
height: 200px;
background: #2c3e50;
top: 47px;
display: none;
text-align: center;
padding-left: 0;
transition: all .5s;
}
#check:checked ~ ul {
display: block;
}
<nav>
<div id="center">
<input type="checkbox" id="check">
<label for="check" class="checkbtn">
<i class="fas fa-bars"></i>
</label>
<ul>
<li>Home</li>
<li>Skill</li>
<li>Profile</li>
</ul>
</div>
</nav>

How to make an input group fill the horizontal space?

I am using bootstrap 4, and I have a navbar for small screens, where I would like a search input group to take the width from left all the way to the right, where I have the menu bar icon. I have made a JSFiddle here. How can I make the input group be flexible and take the remaining space that is on the left side after the menu bar?
I can't seem to get the input inside the input group to take the full width of the form wrapper, I have tried with setting the margin-right same width as the menu-bar but that didn't work since, the input inside the input group didn't take the full width. How can I achieve the desired layout?
This is the navbar:
#media (max-width: 767px) {
.navigation-container .form-wrapper {
width: 100%;
margin-right: 32px;
}
.navigation-container .menu-button {
position: absolute;
}
.navigation-container .navbar {
height: 50px;
}
}
.navigation-container .nav-link {
padding: 0;
}
.navigation-container .navbar {
background: #fff;
flex-direction: inherit;
align-items: center;
padding: 0;
}
.navigation-container .navbar .btn {
font-size: 14px;
}
.navigation-container .navbar .right-side-bar #nav-icon1 {
width: 22px;
top: 10px;
right: 10px;
cursor: pointer;
padding: 0.85rem;
}
.navigation-container .navbar .right-side-bar #nav-icon1 span {
display: block;
position: absolute;
height: 4px;
width: 100%;
background: #008489;
border-radius: 8px;
opacity: 1;
left: 0;
}
.navigation-container .navbar .right-side-bar #nav-icon1 span:nth-child(1) {
top: 0.3rem;
}
.navigation-container .navbar .right-side-bar #nav-icon1 span:nth-child(2) {
top: 0.8rem;
}
.navigation-container .navbar .right-side-bar #nav-icon1 span:nth-child(3) {
top: 1.3rem;
}
.navigation-container .navbar .right-side-bar #nav-icon1.open span:nth-child(1) {
top: 0.8rem;
background: #008489;
}
.navigation-container .navbar .right-side-bar #nav-icon1.open span:nth-child(2) {
opacity: 0;
left: -60px;
}
.navigation-container .navbar .right-side-bar #nav-icon1.open span:nth-child(3) {
top: 0.8rem;
background: #008489;
}
.navigation-container input {
border: 0;
}
.navigation-container i {
color: #008489;
font-size: 28px;
}
.navigation-container .input-group-addon {
background: #fff;
border: 0;
padding: 0;
border-radius: 0;
}
.search-button {
background: transparent;
border: 0;
}
.search-button i {
font-size: 22px;
}
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" rel="stylesheet"/>
<link href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css" rel="stylesheet"/>
<div class="navigation-container">
<div class="container top-menu">
<nav class="navbar navbar-light bg-faded">
<div class="hidden-md-up nav-small">
<div class="form-wrapper">
<form action="/search" method="get">
<div class="input-group">
<span class="input-group-addon">
<button type="submit" class="search-button">
<i class="ion-ios-search-strong"></i>
</button>
</span>
<input type="text" name="q" class="search-input form-control aa-input-search" placeholder="Search for players and videos ..." aria-describedby="basic-addon1">
</div>
</form>
</div>
<div class="right-side-bar">
<div id="nav-icon1" class="menu-button hidden-md-up">
<span></span>
<span></span>
<span></span>
</div>
</div>
</div>
<div class="navbar-collapse collapse justify-content-between" id="navbar5">
<form action="/search" method="get" class="my-auto d-inline mx-auto col-md-8" role="search">
<div class="input-group big-screen-search-form">
<span class="input-group-addon" id="basic-addon1">
<button type="submit" class="search-button">
<i class="ion-ios-search-strong"></i>
</button>
</span>
<input type="text" id="search-input" name="q" class="search-input form-control aa-input-search" placeholder="Search for players and videos ..." aria-describedby="basic-addon1">
</div>
</form>
<ul class="navbar-nav my-auto">
<li class="nav-item dropdown">
<a class="nav-link" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="ion-ios-gear-outline"></i>
</a>
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdownMenuLink">
<a class="dropdown-item" href="#">Admin dashboard</a>
<a class="dropdown-item">
Log out
</a>
</div>
</li>
</ul>
</div>
</nav>
</div>
</div>
If you don't want to use flex, you can use a width calc and just make room for the hamburger button:
.nav-small { width: calc(100% - 40px); }
The problem is your internal .nav-small is not getting flex properties, so it isn't sizing. If I give it flex grow (1 0 0) and also make it display:flex so its internal pieces position properly, it works.
Here's a fiddle: https://jsfiddle.net/s1vz7xt3/5/ - I simply added
.nav-small {
flex: 1 0 0;
display: flex;
}

CSS styling for input tags inside labels

I am using the below filter to sort a list:
<fieldset class="groups">
<h4 class="cufon_headings">Groups</h4>
<div class="checkbox">
<input type="checkbox" value="member1">
<label>Member 1</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" value="member2">
Member 2</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" value="member3">
Member 3</label>
</div>
</fieldset>
This is my CSS for the above filter:
/* Checkbox Styles*/
fieldset {
display: inline-block;
vertical-align: top;
margin: 0 1em 0 0;
background: #fff;
padding: .5em;
border-radius: 3px;
}
.checkbox{
display: block;
position: relative;
cursor: pointer;
margin-bottom: 8px;
}
.checkbox input[type="checkbox"]{
position: absolute;
display: block;
top: 0;
left: 0;
height: 100%;
width: 100%;
cursor: pointer;
margin: 0;
opacity: 0;
z-index: 1;
}
.checkbox label{
display: inline-block;
vertical-align: top;
text-align: left;
padding-left: 2em;
}
.checkbox label:before,
.checkbox label:after{
content: '';
display: block;
position: absolute;
}
.checkbox label:before{
left: 0;
top: 0;
width: 18px;
height: 18px;
margin-right: 10px;
background: #ddd;
border-radius: 3px;
}
.checkbox label:after{
content: '';
position: absolute;
top: 4px;
left: 4px;
width: 10px;
height: 10px;
border-radius: 2px;
background: #E50082;
opacity: 0;
pointer-events: none;
}
.checkbox input:checked ~ label:after{
opacity: 1;
}
.checkbox input:focus ~ label:before{
background: #eee;
}
The first checkbox (Member 1) is correctly styled, i.e. checking the first option marks the checkbox magenta. In this example the tag is outside of the tags.
The other chekcbox options (Member 2 and Member 3) do not turn magenta upon selecting them. With both the tag is inside the tag.
The preferred variant is having the tags inside the tags. However, I could not figure out how to adapt the CSS to get this working. Can anyone provide help? (Here is a link to the code on CopePen)
<fieldset class="groups">
<h4 class="cufon_headings">Groups</h4>
<div class="checkbox">
<input type="checkbox" value="member1">
<label>Member 1</label>
</div>
<div class="checkbox">
<input type="checkbox" value="member2">
<label>Member 2</label>
</div>
<div class="checkbox">
<input type="checkbox" value="member3">
<label>Member 3</label>
</div>
</fieldset>
Make sure that your labels are correct for member 2 and 3. You had the label tag including the input tag. The code above seems to work.
Charlie's answer is correct. In CSS, you can't affect a parent - only a child.
before and after are puesdo elements and they're not exactly acting like normal elements, so they're not siblings of input.
In order to solve your problem, Change every:
<div class="checkbox">
<label>
<input type="checkbox" value="memberN">
Member N
</label>
</div>
Into:
<div class="checkbox">
<input type="checkbox" value="memberN">
<label>
Member N
</label>
</div>
Thank you for your comments. It was intended that the first checkbox differs from the others to show the effect.
If it is not possible with CSS I guess I need to adapt how the plugin Contact Form 7 for Wordpress gives out the HTML for checkboxes. Not the preferred way to handle the issue.

How to change active tab to first css

Here is the code:
.tabs {
float: right;
position: relative;
min-height: 140px;
margin: 25px 0;
width: 500px;
}
.tab {
float: left;
}
.tab label {
background: #eee;
padding: 10px;
border: 1px solid #ccc;
margin-left: -1px;
position: relative;
left: 1px;
}
.tab [type=radio] {
display: none;
}
.content {
position: absolute;
top: 28px;
left: 0;
background: white;
right: 0;
bottom: 0;
padding: 20px;
border: 1px solid #ccc;
}
[type=radio]:checked ~ label {
background: white;
border-bottom: 1px solid white;
z-index: 2;
}
[type=radio]:checked ~ label ~ .content {
z-index: 1;
}
HTML structure:
<div class="tabs">
<div class="tab">
<input type="radio" id="tab-1" name="tab-group-1" checked>
<label for="tab-1">Tab-1</label>
<div class="content">
bla-bla1
</div>
</div>
<div class="tab">
<input type="radio" id="tab-2" name="tab-group-1" checked>
<label for="tab-2">Tab-2</label>
<div class="content">
bla-bla2
</div>
</div>
</div>
This code makes the second tab is active. But I need the first tab. I don't really get in my mind what attributes should I change. The code structure for all tabs is the same, only the "id" attribute is different. If I add third tab, third tab will be active.
Here you go: Fiddle
HTML:
<input type="radio" id="tab-2" name="tab-group-1" /> // remove checked
Explanation: Since you have checked attributes applied to both input.
Your tabs have radios:
<input type="radio" id="tab-2" name="tab-group-1" checked>
remove checked from all radios except first.
Demo Link
Only one tab at one time may be active.
When a tab is clicked it becomes an active tab.
If you need first tab to make active, add checked to only first tab. remove checked from others.
<input type="radio" id="tab-2" name="tab-group-1" checked/>

Aligning Radio Buttons Below a DIV

Disclaimer: I am a VB guy with 4 days of jQuery and CSS experience. I am just trying to figure out the web design world!
I want to learn how to approach a design like this:
!(http://i.imgur.com/tDlRxnh.jpg)
Figuring it out from the image, I believe there's an outer div with an image center aligned and a white border around the image
The image has a left and right button on either sides that overlaps the images (God knows how's that even possible!)
Below the Outer Div are four radio buttons aligned one after the other
How to go about this design? (interested in just the design, not the coding part)
Comments/explanations would help! Thanks.
Edit: With my 16 hrs of experience, this is what I have so far http://jsfiddle.net/29mH2/2/. Sorry for being such a n00b!
<div id="somediv">
<img src=""/>
<img src=""/>
<img src=""/>
</div>
<input type="radio" name="op">
<input type="radio" name="op">
<input type="radio" name="op">
<input type="radio" name="op">
div {
background-color:blue;
border: 2px white;
position: absolute;
}
img {
display: none;
position: absolute;
}
Since you mentioned you're working with jQuery already, take a look at this tutorial and a working example of the result.
Basically, you're going to want to make two list elements.
One will contain the slides, and the other will contain the navigation buttons.
EDIT:
Since you're just looking for an example of the design, Here's a basic example that shows how to make a layout like you're talking about without any actual functionality.
HTML:
<div class="slider">
<img class="image" src="http://i.imgur.com/dL3io.jpg" />
<div class="navigation-arrows">
<div class="arrow left"><</div>
<div class="arrow right">></div>
</div>
</div>
<div class="navigation">
<input type="radio" name="op">
<input type="radio" name="op">
<input type="radio" name="op">
<input type="radio" name="op">
</div>
CSS:
body {
text-align: center;
}
.slider,
.slider .image {
width: 400px;
}
.slider .image,
.navigation-arrows,
.navigation-arrows .arrow {
position: absolute;
}
.navigation-arrows,
.navigation-arrows .arrow {
height: 25px;
}
.slider {
height: 250px;
position: relative;
margin: 20px auto;
}
.slider .image {
height: 250px;
left: 0;
top: 0;
}
.navigation-arrows {
width: 100%;
margin: 0 auto;
top: 125px;
}
.navigation-arrows .arrow {
border-radius: 12.5px;
background: #000000;
color: #ffffff;
width: 25px;
line-height: 25px;
cursor: pointer;
}
.navigation-arrows .left {
left: 5px;
}
.navigation-arrows .right {
right: 5px;
}

Resources