Equal height via script - javascript

It's a pain to use equal height with pure css that support at least ie9 and good browsers.
So, I'm decided to use js instead. If there's no js enabled on the user side, having not equal heights are the least of my problems.
However, I have a very specific request on this "equal height" situation.
Using flex, with the help of other SO user, we can have:
http://jsfiddle.net/4an5r1b3/1/
HTML
<div class="container">
<div class="col left">
<p>lorem ipsium</p>
<p>lorem ipsium</p>
<p>lorem ipsium</p>
<p>lorem ipsium</p>
<div class="bottom-yeah">
<p>lorem ipsium</p>
<p>lorem ipsium</p>
<p>lorem ipsium</p>
</div>
</div>
<div class="col right">
<p>lorem ipsium</p>
<p>lorem ipsium</p>
<p>lorem ipsium</p>
<p>lorem ipsium</p>
<p>lorem ipsium</p>
<p>lorem ipsium</p>
<p>lorem ipsium</p>
<p>lorem ipsium</p>
<p>lorem ipsium</p>
<p>lorem ipsium</p>
<p>lorem ipsium</p>
<p>lorem ipsium</p>
<p>lorem ipsium</p>
</div>
</div>
CSS:
.container{
display: flex;
}
.col {
float: left;
width: 30%;
color: #fff;
}
.col.left {
display: flex;
flex-direction: column;
background-color: transparent;
color: red;
}
.col.right {
background-color: blue;
}
.bottom-yeah {
flex-grow: 1;
margin-top: 50px;
background-color: yellow;
}
I'm wondering if we can achieve the same thing,
using jquery so that, old browsers could behave as well?
Any known script that does this, so that we don't re-invent the wheel here?

var leftHeight = $('.col.left').height();
var rightHeight = $('.col.right').height();
if (leftHeight > rightHeight)
{
$('.col.right').height(leftHeight);
} else {
$('.col.left').height(rightHeight);
}
If your site is responsive, you can put this in a function and call it on $(window).resize

Related

My border-bottom doesn't disappear when it's on another div class

I have a question. I have a filtering feature with a button. I have the code below that I'm working on. The problem is, what I want when the button is active, the border-bottom color changes color. In the code that I created, I have managed to provide a condition when it is active. but when I select another button, the border-bottom that is in the previous button is not removed perfectly.
I want the bottom border on the active button to be #0f0f0f and on the inactive button to be #FAFAFA. Where is the missing code or wrong with my code?
$(document).ready(function(){
$('.list-content').css('display','none');
$('.all').show();
$('button').on("click" , function(){
let target = $(this).data('target');
let content = $('.list-content').data('content');
console.log(target);
$('li#' + target).addClass('active');
$('.list-content').hide();
$('.' + target).show();
});
});
body{
background-color:#CACACA;
}
.list-tag ul{
display:flex;
list-style: none;
padding: 0;
margin: 0;
}
.list-tag ul li{
border-bottom: 1px solid #FAFAFA;
}
.list-tag ul li.active{
border-bottom: 1px solid #0f0f0f;
}
button{
padding:5px 10px;
border:none;
background:transparent;
boder-bottom:1px solid red;
cursor:pointer;
}
button:focus{
outline:none;
box-shadow:none;
}
.content{
margin-top:20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="list-tag">
<ul>
<li id="all">
<button data-target="all"> All</button>
</li>
<li id="tech">
<button data-target="tech">Tech</button>
</li>
<li id="industry">
<button data-target="industry">Industry</button>
</li>
<li id="edu">
<button data-target="edu">Education</button>
</li>
</ul>
</div>
<div class="content">
<div class="list-content all" id="all">Lorem ipsum All.</div>
<div class="list-content all" id="all">Lorem ipsum All.</div>
<div class="list-content all" id="all">Lorem ipsum All.</div>
<div class="list-content all" id="all">Lorem ipsum All.</div>
<div class="list-content tech" id="tech">Lorem ipsum Tech.</div>
<div class="list-content tech" id="tech">Lorem ipsum Tech.</div>
<div class="list-content tech" id="tech">Lorem ipsum Tech.</div>
<div class="list-content tech" id="tech">Lorem ipsum Tech.</div>
<div class="list-content industry" id="industry">Lorem ipsum Industry.</div>
<div class="list-content industry" id="industry">Lorem ipsum Industry.</div>
<div class="list-content industry" id="industry">Lorem ipsum Industry.</div>
<div class="list-content industry" id="industry">Lorem ipsum Industry.</div>
<div class="list-content edu">Lorem ipsum Edu.</div>
<div class="list-content edu">Lorem ipsum Edu.</div>
<div class="list-content edu">Lorem ipsum Edu.</div>
<div class="list-content edu">Lorem ipsum Edu.</div>
</div>
$(document).ready(function(){
$('.list-content').css('display','none');
$('.all').show();
$('button').on("click" , function(){
let target = $(this).data('target');
let content = $('.list-content').data('content');
console.log(target);
$('li.active').removeClass('active'); // You need to add this line so that it can remove border from active item.
$('li#' + target).addClass('active');
$('.list-content').hide();
$('.' + target).show();
});
});
I wouldn't put the border-bottom to the li-element as that will never have the focus-status, here is an example where the border is applied to the button itself. Maybe this works for you:
$(document).ready(function(){
$('.list-content').css('display','none');
$('.all').show();
$('button').on("click" , function(){
let target = $(this).data('target');
let content = $('.list-content').data('content');
console.log(target);
$('li#' + target).addClass('active');
$('.list-content').hide();
$('.' + target).show();
});
});
body{
background-color:#CACACA;
}
.list-tag ul{
display:flex;
list-style: none;
padding: 0;
margin: 0;
}
button{
padding:5px 10px;
border:none;
background:transparent;
border-bottom:1px solid #FAFAFA;
cursor:pointer;
}
button:focus{
outline:none;
box-shadow:none;
border-bottom: 1px solid #0f0f0f;
}
.content{
margin-top:20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="list-tag">
<ul>
<li id="all">
<button data-target="all"> All</button>
</li>
<li id="tech">
<button data-target="tech">Tech</button>
</li>
<li id="industry">
<button data-target="industry">Industry</button>
</li>
<li id="edu">
<button data-target="edu">Education</button>
</li>
</ul>
</div>
<div class="content">
<div class="list-content all" id="all">Lorem ipsum All.</div>
<div class="list-content all" id="all">Lorem ipsum All.</div>
<div class="list-content all" id="all">Lorem ipsum All.</div>
<div class="list-content all" id="all">Lorem ipsum All.</div>
<div class="list-content tech" id="tech">Lorem ipsum Tech.</div>
<div class="list-content tech" id="tech">Lorem ipsum Tech.</div>
<div class="list-content tech" id="tech">Lorem ipsum Tech.</div>
<div class="list-content tech" id="tech">Lorem ipsum Tech.</div>
<div class="list-content industry" id="industry">Lorem ipsum Industry.</div>
<div class="list-content industry" id="industry">Lorem ipsum Industry.</div>
<div class="list-content industry" id="industry">Lorem ipsum Industry.</div>
<div class="list-content industry" id="industry">Lorem ipsum Industry.</div>
<div class="list-content edu">Lorem ipsum Edu.</div>
<div class="list-content edu">Lorem ipsum Edu.</div>
<div class="list-content edu">Lorem ipsum Edu.</div>
<div class="list-content edu">Lorem ipsum Edu.</div>
</div>
Just be aware: in your original code the "border-bottom" for the button has a typo "boder-bottom"
You need to remove the active class from the previous li as you click on a different button.
Couple of ways come to mind to achieve this.
$('.list-content').css('display','none');
$('.all').show();
$('button').on("click" , function() {
let target = $(this).data('target');
let content = $('.list-content').data('content');
console.log(target);
// Add one of these
// 1. $('li.active').removeClass('active') OR
// 2. $(`li:not(#${target})`).removeClass('active')
$('li#' + target).addClass('active');
$('.list-content').hide();
$('.' + target).show();
});
});

Equal height column across two divs

I have been searching and cannot find an answer to this question. I have two divs, one contains one column and the other contains two columns. I am looking to get the three columns to equal heights across the the tow divs. I am sure this is possible I just don't know it yet. Here is code below. As you can see I can get them to align across the bottom but I am missing something.
.cplan-section{
display: flex;
}
.technical-products{
width:33%;
}
.training-products{
width:66%;
}
.section-title{
padding: 30px 0;
}
.technical-products, .training-products{
display:flex;
flex-direction: column;
justify-content: space-between;
}
.cproducts, .train-video, .job-aids{
padding:10px;
}
.col-header p{
display: inline-block;
vertical-align: middle;
line-height: normal;
}
.col-body{
padding:0 10px;
color:#000;
background-color: #d5deed;
}
.col-header{
min-height: 100px;
line-height: 100px;
text-align: center;
background-color: #98cb42;
color:#fff;
}
.col-tp{
width:50%;
border:2px solid #000;
}
.col-cp{
border:2px solid #000;
}
.sectioncp, .sectiontp{
display:flex;
}
.col-tp{
flex-direction:vertical;
}
.cp-header, .tv-header, .ja-header{
background-color:#98cb42;
color:#fff;
padding:5px
}
/*media for plan section */
#media (max-width: 767px){
.covid-plan-section{
display: inline;
}
.technical-products, .training-products{
display:block;
}
.technical-products{
width:100%;
}
.training-products{
width:100%;
}
.sectiontp{
display:flex;
}
.col-tp{
display:flex;
flex-direction: column;
justify-content: space-between;
}
}
#media (max-width: 479px){
.covid-plan-section{
display: block;
}
.technical-products, .training-products{
display:block;
}
.technical-products{
width:100%;
}
.training-products{
width:100%;
}
.sectiontp{
display:inline;
}
.col-tp{
width:100%;
}
}
<div class=cplan-section>
<div class=technical-products>
<div class=section-title>
<h2 style="text-align: center;">This is Section 1</h2>
</div>
<div class=sectioncp>
<div class=col-cp>
<div class=cproducts>
<div class=col-header>
<p style="text-align: center;">Title 1</p>
</div>
<div class=col-body>
<ul>
<li>Lorem Ipsum is simply dummy text of the printing and typesetting industry.</li>
<li>Lorem Ipsum is simply dummy text of the printing and typesetting industry.</li>
<li>Lorem Ipsum is simply dummy text of the printing and typesetting industry.</li>
<li>Lorem Ipsum is simply dummy text of the printing and typesetting industry.</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div class=training-products>
<div class=section-title>
<h2 style="text-align: center;">This is section 2</h2>
</div>
<div class=sectiontp>
<div class=col-tp>
<div class=train-video>
<div class=col-header>
<p style="text-align: center;">Title 2</p>
</div>
<div class=col-body>
<ul>
<li>Lorem Ipsum is simply dummy text of the printing and typesetting industry.</li>
<li>Lorem Ipsum is simply dummy text.</li>
</ul>
</div>
</div>
</div>
<div class=col-tp>
<div class=job-aids>
<div class=col-header>
<p style="text-align: center;">Title 2</p>
</div>
<div class=col-body>
<ul>
<li>Lorem Ipsum</li>
<li>Lorem Ipsum</li>
<li>Lorem Ipsum text</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
Your proposal, without setting a height or min-height property is not possible.
"Same-height" elements have no possibility of doing that, without referencing siblings in the same "line" using flexbox.
What you could do (unorthodox, almost a bad practice if you will be needing to dynamize, I'm guessing you won't), at least is my solution for your problem is to put it all together in the same flex container, one after the other.
That will end up as:
.title1
.title2
.col1
.col2
.col3
Rendering this:
But how? Your structure simplified:
<div class="cplan-section">
<div class="products">
<div class="title1">
<h2 style="text-align:center;">This is Section 1</h2>
</div>
<div class="title2">
<h2 style="text-align:center;">This is section 2</h2>
</div>
<div class="col1">
<div class="cproducts">
<div class="col-header">
<p style="text-align: center;">Title 1</p>
</div>
<div class="col-body">
<ul>
<li>Lorem Ipsum is simply dummy text.</li>
<li>Lorem Ipsum is simply dummy text.</li>
<li>Lorem Ipsum is simply dummy text.</li>
<li>Lorem Ipsum is simply dummy text.</li>
<li>Lorem Ipsum is simply dummy text.</li>
<li>Lorem Ipsum is simply dummy text.</li>
<li>Lorem Ipsum is simply dummy text.</li>
<li>Lorem Ipsum is simply dummy text.</li>
<li>Lorem Ipsum is simply dummy text.</li>
<li>Lorem Ipsum is simply dummy text.</li>
<li>Lorem Ipsum is simply dummy text.</li>
<li>Lorem Ipsum is simply dummy text.</li>
<li>Lorem Ipsum is simply dummy text.</li>
<li>Lorem Ipsum is simply dummy text.</li>
<li>Lorem Ipsum is simply dummy text.</li>
<li>Lorem Ipsum is simply dummy text.</li>
</ul>
</div>
</div>
</div>
<div class="col2">
<div class="train-video">
<div class="col-header">
<p style="text-align: center;">Title 2</p>
</div>
<div class="col-body">
<ul>
<li>Lorem Ipsum is simply dummy text.</li>
<li>Lorem Ipsum is simply dummy text.</li>
<li>Lorem Ipsum is simply dummy text.</li>
<li>Lorem Ipsum is simply dummy text.</li>
<li>Lorem Ipsum is simply dummy text.</li>
<li>Lorem Ipsum is simply dummy text.</li>
</ul>
</div>
</div>
</div>
<div class="col3">
<div class="job-aids">
<div class="col-header">
<p style="text-align: center;">Title 2</p>
</div>
<div class="col-body">
<ul>
<li>Lorem Ipsum</li>
<li>Lorem Ipsum</li>
<li>Lorem Ipsum text</li>
</ul>
</div>
</div>
</div>
</div>
</div>
And this is your CSS:
html { padding:30px; }
* { font-family:"Arial", sans-serif; box-sizing:border-box; }
.cplan-section .products {
width:100%;
display:flex;
flex-wrap:wrap;
border:1px solid #aaa;
padding:10px;
}
.cplan-section .products div[class^="title"] {
text-align:left;
padding-left:20px;
}
.cplan-section .products .col1,
.cplan-section .products .col2,
.cplan-section .products .col3 {
border:1px solid #777;
padding:10px;
}
.cplan-section .products .title1,
.cplan-section .products .col1 { flex-basis:40%; }
.cplan-section .products .title2 { flex-basis:60%; }
.cplan-section .products .col2,
.cplan-section .products .col3 { flex-basis:30%; }
#media (max-width:479px) {
.cplan-section .products {
flex-direction:row;
flex-wrap:wrap;
}
.cplan-section .products div[class^="title"],
.cplan-section .products div[class^="col"] { flex-basis:100%; }
.cplan-section .products .title1,
.cplan-section .products .col1 { order:-2; }
.cplan-section .products .title2 { order:-1; }
}
That's ok, but, what about when we stack elements in a mobile/responsive view? They will be badly organized.
Ok, by default every flex element contained has a 0 'order' value, and they stack for rendering in order of appearance. So if I modify that property for the first 3 elements, that should do it.
Take a look at the bottom of the CSS code.
And this is how viewport 479px and under should look:
Fiddle: https://jsfiddle.net/Dethdude/ch0mrgbe/23/

Show hidden nth-child items onclick

I have a list of content which is all viewable on desktop. On mobile, I have hidden some of the content and want to add a button, which on click, would show the hidden content.
I'm aware of how to hide and show div's on click, ie.
function showClass(id) {
var elem = document.getElementById(id);
var visible = getComputedStyle(elem).display == "block";
if (!visible) {
elem.style.display = "block"
} else {
elem.style.display = "none"
}
}
But unsure on how to approach this for items that are in the same class that are hidden via nth-child?
Markup:
#media(max-width: 576px){
.wrapper:nth-of-type(n+4) {
display: none;
}
}
.showmore{
display: none;
}
#media(max-width: 576px){
.showmore{
display: block;
}
}
<div class="container">
<div class="wrapper">
<p>test 1</p>
</div>
<div class="wrapper">
<p>test 2</p>
</div>
<div class="wrapper">
<p>test 3</p>
</div>
<div class="wrapper">
<p>test 4</p>
</div>
<div class="wrapper">
<p>test 5</p>
</div>
<div class="wrapper">
<p>test 6</p>
</div>
<a class="showmore" onclick="show">Show more</a>
</div>
Use the :not() pseudo-class to only hide the items when the .show-all class is not present on the container:
const container = document.querySelector('.container')
const showmore = document.querySelector('.showmore')
showmore.addEventListener('click', () =>
container.classList.toggle('show-all')
)
.showmore{
display: none;
}
#media(max-width: 576px){
.container:not(.show-all) .wrapper:nth-of-type(n+4) {
display: none;
}
.showmore{
display: block;
}
}
<div class="container">
<div class="wrapper">
<p>test 1</p>
</div>
<div class="wrapper">
<p>test 2</p>
</div>
<div class="wrapper">
<p>test 3</p>
</div>
<div class="wrapper">
<p>test 4</p>
</div>
<div class="wrapper">
<p>test 5</p>
</div>
<div class="wrapper">
<p>test 6</p>
</div>
<a class="showmore">Show more</a>
</div>
I'd first change the placement of the "show more" link in the markup, in order to keep a more consistent order of reading.
With this approach you need to hide all the sibling elements of the link and the click event just removes the link itself, showing all the remaining content.
In this example the link is visible under 640px (open the demo in a full page) and I've also inserted a small fade effect over the text before the link (just remove the linear gradient if you are not interested)
document.querySelector('.showmore').addEventListener('click', function(ev) {
ev.preventDefault();
this.remove();
})
.showmore {
display: none;
margin-top: -5em;
}
.showmore::before {
content: "";
display: block;
height: 5em;
background: linear-gradient(to bottom, transparent, #fff);
}
#media all and (max-width:640px) {
.showmore {
display: block;
position: relative;
}
.showmore ~ * { display: none; }
}
<div class="container">
<div class="wrapper">
<p>Lorem ipsum sit dolor amet consectetur dolor adisciplit elit sed diam nonummy pellentesque.</p>
</div>
<div class="wrapper">
<p>Lorem ipsum sit dolor amet consectetur dolor adisciplit elit sed diam nonummy pellentesque.</p>
</div>
<div class="wrapper">
<p>Lorem ipsum sit dolor amet consectetur dolor adisciplit elit sed diam nonummy pellentesque.</p>
</div>
<div class="wrapper">
<p>Lorem ipsum sit dolor amet consectetur dolor adisciplit elit sed diam nonummy pellentesque.</p>
</div>
<a class="showmore" href="#">Show more</a>
<div class="wrapper">
<p>Lorem ipsum sit dolor amet consectetur dolor adisciplit elit sed diam nonummy pellentesque.</p>
</div>
<div class="wrapper">
<p>Lorem ipsum sit dolor amet consectetur dolor adisciplit elit sed diam nonummy pellentesque.</p>
</div>
</div>

How to set a variable for the parent's css class using the parent's variable for its id?

So what I want to do first is to set a variable for the parent using the id of it. Then I want to use this variable to find the css class of the parent and set a new variable again. It's important use the variable for the parent's id because later I want to change HTML style of this class with the specific id. My JS works fine without "var parent = parentid.find('.parent');"... I don't know what's wrong.
var parentid = document.getElementById('1');
var parent = parentid.find('.parent');
parent.style.background = "yellow";
.parent {
width: 150px;
line-height: 2.5ex;
max-height: 12.5ex;
border: 1px solid red;
background: white;
margin: 10px;
padding: 10px;
overflow: hidden;
}
<div class="parent" id="1">
Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum
</div>
jQuery's .find() doesn't include the selector itself into it's search, you have to use .closest() (begins with the current element) instead:
var parentid = $('#1');
var parent = parentid.closest('.parent');
$(parent).css('background-color', 'gold');
.parent {
width: 150px;
background: pink;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parent" id="1">
The CSS 'background-color' property is PINK.
</div>
In your example, as long as the element only has a single class, you can just reference className
var parentid = document.getElementById('1');
var parent = document.getElementsByClassName(parentid.className)[0];
parent.style.background = "yellow";
.parent {
width: 150px;
line-height: 2.5ex;
max-height: 12.5ex;
border: 1px solid red;
background: white;
margin: 10px;
padding: 10px;
overflow: hidden;
}
<div class="parent" id="1">
Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum
</div>

showing a div content after scrolling down

hi there i'm trying to show a hidden div when scrolling down from the top of the browser page, like the Accordion function. What i'm using here is this Code:
HTML:-
// Visible DIV
<div class="firstBlock">
<p>Lorem ipsum dolor sit Amet, consectetuer adipiscing.</p>
</div>
// Hiddden DIV
<div class="textBlock">
<p>Lorem ipsum dolor sit Amet, consectetuer adipiscing.</p>
</div>
// Visible DIV
<div class="secondBlock">
<p>Lorem ipsum dolor sit Amet, consectetuer adipiscing.</p>
</div>
CSS:-
.textBlock {
text-align: center;
height: 104px;
width: 100%;
float: left;
display: none;
}
.textBlock p {
font-size: 16px;
font-family: arial,helvetica,sans-serif;
padding: 10% 5%;
line-height: 20px;
}
jQuery:-
$(document).ready(function(){
$(window).bind("scroll", function() {
if ($(this).scrollTop() > 600) {
$(".textBlock").fadeIn();
} else {
$(".textBlock").stop().fadeOut();
}
});
});
but it needs some modification in order to work like Accordion-Function.
If you want the accordion effect you should use the slideDown and slideUp functions (docs here), like so:
http://jsfiddle.net/b7yomjd0/3/

Categories

Resources