How to always fill the parent height using flexbox? - javascript

I have the following HTML:
<div class="admonition info">
<p class="admonition-title">Info</p>
<p>Text here</p>
</div>
And CSS:
.admonition {
border: 1px solid red;
display: flex;
justify-content: center;
align-items: center;
}
.admonition > p {
margin: 0;
padding: 6px;
display: block;
}
.admonition-title {
background-color: #2B83BD;
color: #fff;
display: block;
padding: 2px;
}
.admonition > .admonition-title {
font-size: 1px;
letter-spacing: -1px;
color: transparent;
width: 64px;
text-align: center;
vertical-align: middle;
min-width: 60px;
}
.admonition > .admonition-title:before {
font-family: "FontAwesome";
font-size: 32px;
letter-spacing: normal;
color: #fff;
}
.admonition.info > .admonition-title:before {
content: "\f129";
}
.admonition.info > p:not(.admonition-title) {
background-color: #7DBAE3;
}
.admonition.info > .admonition-title {
background-color: #2B83BD;
}
I would like to render the children with the following constraints:
They are vertically centered
If their height is not equal, they should stretch to fill the gaps
The white gaps are what I would like to avoid. Live on JSFiddle
The HTML is generated from markdown and I don't really have control over the structure. Is this possible to implement in a simple way? Javascript, jquery is also OK, but I'd prefer to do this in CSS.

Just use align-items: stretch; to make the items fill the parent height.
Then, your icon will need to be centered manually, I have done it with:
.admonition > .admonition-title {
display: flex;
align-items: center;
justify-content: center;
}
https://jsfiddle.net/4mw8a08x/

Related

How do you remove the blinking cursor when clicking on text in a div (not <input>)

So I'm building a fun little Jeopardy (They reserve all of their rights) game for my work.
Building it using grid is super easy and all, but when I click on the <div> it adds the blinking text cursor after it (as shown in the picture below).
I tried doing cursor: default and cursor: none -- none made the JS stop functioning, and default didn't do anything (that's what the picture has).
CSS
#round-one {
display: grid;
grid-template-columns: 200px 200px 200px 200px 200px;
grid-template-rows: 100px 100px 100px 100px 100px 100px;
gap: 20px;
background-color: black;
width: 1080px;
height: 700px;
border: 20px solid black;
}
.round>div,
.round>span {
background-color: #021489;
display: inline-grid;
height: 100px;
width: 200px;
cursor: default; /** Same Location I tried cursor: none **/
}
.header {
font-variant: small-caps;
font-weight: bold;
color: white;
justify-content: center;
align-items: center;
font-size: 2em;
text-align: center;
}
.answer {
font-weight: bold;
color: #D7A04B;
justify-content: center;
align-items: center;
font-size: 4em;
text-align: center;
}
HTML Section
<body>
<div id="round-one" class="round">
<div id="r1c1r1" class="answer" onclick="question('r1c1r1')">
100
</div>
and JS
<script>
function question(id) {
alert("test");
}
</script>
I'll deal with the actual JS I'll be using later. As it stands right now, the cursor: default allows me to click and receive the alert().
I use caret-color: transparent; for my forms where I find the blinking caret distracting. Technically the caret will still be "there" Just invisible.

flexbox is misbehaving with javascript active class

Navbar
Beginner here
As you can see everything is working perfectly until you click on the space between the links you can check here- my codepen. when I click on the links navbar it perfectly shows the active class, but if I click in between the space the whole navbar loses the class.
var element = document.getElementsByClassName("flex-nav")[0];
element.addEventListener("click", myFunction);
function myFunction(e) {
var elems = document.querySelector(".active");
if(elems !==null) {
elems.classList.remove("active");
}
e.target.className = "active";
}
.flex-nav {
display: flex;
flex-direction: column;
margin-top: 54px;
background: #333;
width: 75px;
height: 657px;
justify-content: space-around;
align-items: stretch;
line-height: 23px;
}
.flex-nav a{
text-decoration: none;
color: white;
flex-wrap: wrap;
text-align: center;
margin: 5px;
border: 1px solid transparent;
}
.flex-nav a.active {
background: #9999ff;
}
.flex-nav a:hover:not(.active) {
background: #555;
border: 1px solid rgba(255, 51, 153,1);
}
<div class="flex-nav">
2k
4k
1080p
8k
</div>
You can avoid that behaviour by letting the flex items grow so that there is no space between them: Add these settings to .flex-nav a
flex-grow: 1;
display: flex;
justify-content: center;
align-items: center;
(The first is for the growing, the others are for centering the text inside them)

Need to put the image and text on same line

This is how it's looking
i need to make the icon and the text on the same line and close to each other, i tried usingdisplay: inline-block; but it didn't work, here's my code.
HTML:
<div className="Comment_Icon">
<img src={StudentIcon} alt="StudentIcon" class="Student_Icon"></img>
<div className="Comments">5 Class Comments</div>
</div>
CSS:
.Student_Icon {
height: 1vw;
width: 1vw;
display: inline-block;
}
.IconText {
padding-top: 0.8vw;
font-size: 1.5vw;
}
.Comments {
font-size: 2.5vw;
display: inline-block;
}
Use flex in this case as shown below
.IconText {
padding-top: 0.8vw;
font-size: 1.5vw;
}
.Comments {
font-size: 2.5vw;
display: inline-block;
}
.Comment_Icon {
display: flex;
flex-direction: row;
align-items: center;
}
.Student_Icon {
margin-right: 3px;
}
<div class="Comment_Icon">
<img src={StudentIcon} alt="StudentIcon" class="Student_Icon"></img>
<div class="Comments">5 Class Comments</div>
</div>
.Student_Icon {
float: left;
padding-right: 10px;
}
.IconText {
padding-top: 0.8vw;
font-size: 1.5vw;
}
.Comments {
font-size: 2.5vw;
display: inline-block;
}
<div className="Comment_Icon">
<img src=https://via.placeholder.com/20 class="Student_Icon"></img>
<div className="Comments">5 Class Comments</div>
</div>
I made use of float: left;
So the icon/image comes left and the text next to it.
You can achieve this with flexbox styling. Note that I am changing your React structure a bit and also adding a fake image. And did you mean to use 1vw? that means 1% of the viewport width and is pretty small - esp on small screens.
Using and referencing REM units is more reliable ( REM is set in the root element and is usually 16px but can be changed. But the advantage of using rems is that it is a common size that all elements can access.
.Comment_Icon {
display: flex;
align-items: center;
}
.Student_Icon {
height: 1.5rem;
width: 1.5rem;
}
.Comments {
font-size: 1rem;
margin-left: 8px;
}
<div class="Comment_Icon">
<img src="https://hipsiti.com/uploads/default-profile.png" alt="StudentIcon" class="Student_Icon"/>
<span class="Comments">5 Class Comments</span>
</div>

Change the flex-direction on button click

I am trying to create an animation effect that moves two buttons when I click on them. I have the flex direction set up as a column in the container div and I essentially just want them to position as a flex row when I click on one of them (probably with a 1s animation). When I click on them currently nothing happens. Here is my code sample:
HTML
<header>
<div class="container">
<h1>Choose Your Allegiance</h1>
<div id="buttons">
<button class="fill"><img src="/assets/Jedi.png" alt="Jedi" /></button>
<button class="fill sith">
<img src="/assets/Sith.png" alt="Sith" />
</div>
</button>
</div>
</header>
CSS
.container {
width: 100vw;
display: flex;
flex-direction: column;
align-items: center;
}
.container.click {
flex-direction: row;
justify-content: space-around;
}
h1 {
margin-left: 5vw;
color: black;
font-family: "Poller One", cursive;
font-variant: small-caps;
font-size: 3rem;
margin-top: 6vh;
}
button {
color: white;
transition: 0.25s;
float: left;
margin: 2%;
}
button:hover,
button:focus {
border: 2px solid red;
color: black;
}
.fill {
height: 120px;
width: 150px;
background: transparent;
margin-top: 4vh;
outline: none;
border: none;
}
.fill:hover,
.fill:focus {
box-shadow: inset 0 0 0 4.5em #add8e6;
}
.sith:hover,
.sith:focus {
box-shadow: inset 0 0 0 4.5em black;
}
#buttons {
height: 100%;
width: 100vw;
padding-top: 10vh;
display: flex;
justify-content: center;
}
JS
document.querySelector("button").addEventListener("click", () => {
document.querySelector(".container").classList.toggle(".container.click");
});
There are a couple of changes you need to make to get this to work:
1. document.querySelector("button") is only selecting the first button. There are 2 you can add an event listener to the buttons
use document.querySelectorAll("button") to get all the buttons, and then you can loop through them adding an event Listener to each one:
document.querySelectorAll("button").forEach(function(button) {
button.addEventListener("click", () => {
document.querySelector(".container").classList.toggle("click");
});
});
A better way is to add an event listener to the buttons container - you can get the element using getElementById and then add the listener to it:
var buttons = document.getElementById("buttons");
buttons.addEventListener("click", (e) => {
document.querySelector(".container").classList.toggle("click");
});
2. You just use the class name when passing a class into toggle- you don't need the .. Also, you only need to toggle the click class as the container class will always apply. So what you need to use is .toggle("click");
Working Example (without your images):
var buttons = document.getElementById("buttons");
buttons.addEventListener("click", (e) => {
document.querySelector(".container").classList.toggle("click");
});
.container {
width: 100vw;
display: flex;
flex-direction: column;
align-items: center;
}
.container.click {
flex-direction: row;
justify-content: space-around;
}
h1 {
margin-left: 5vw;
color: black;
font-family: "Poller One", cursive;
font-variant: small-caps;
font-size: 3rem;
margin-top: 6vh;
}
button {
color: red;
transition: 0.25s;
float: left;
margin: 2%;
}
button:hover,
button:focus {
border: 2px solid red;
color: black;
}
.fill {
height: 120px;
width: 150px;
background: transparent;
margin-top: 4vh;
outline: none;
border: none;
}
.fill:hover,
.fill:focus {
box-shadow: inset 0 0 0 4.5em #add8e6;
}
.sith:hover,
.sith:focus {
box-shadow: inset 0 0 0 4.5em black;
}
#buttons {
height: 100%;
width: 100vw;
padding-top: 10vh;
display: flex;
justify-content: center;
}
<header>
<div class="container">
<h1>Choose Your Allegiance</h1>
<div id="buttons">
<button class="fill">Jedi</button>
<button class="fill sith">Sith</button>
</div>
</div>
</header>
As for animating this change, unfortunately CSS animations cannot be applied to flexbox direction property.
You are using classList.toggle wrong. You'll need to do this instead:
const container = document.querySelector(".container");
container.classList.toggle("click");
Documentation on Element.classList here.

How to have a tab containing flexible height menu fixed at bottom of window and slide up on click using jQuery?

I tried coding it myself based on research on the internet. I was able to get it fixed at the bottom. When clicking, it does slide out the menu; but it slides out downwards when it should have pushed the tab upwards to display the menu. If I use negative margin and simply change bottom: -150 to bottom: 0px on click, it does produce the desired behavior by sliding it up from past the bottom of the window and it displays correctly. But it means the menu is pushing the page past the bottom of the page rather than simply being hidden. So when it's "hidden", one can simply scroll down and see the full menu which shouldn't be the case.
So rather than using bottom to manipulate it, I tried using $(this).show("slide"). The menu came out looking distorted thanks to using the sliding animation.
Here's the snippet:
var supTabState = false;
$("#dccontainer").css('bottom', '-150px');
$("#dcsupporttab").click(function() {
$('#dcsupportcontainer').slideToggle(500, function() {
//execute this after slideToggle is done
});
supTabState = !supTabState;
if (supTabState) {
// $("#dccontainer").css('bottom', '0px');
$(this).show("slide", {
direction: "down"
}, 1000);
} else {
// $("#dccontainer").css('bottom', '-150px');
$(this).show("slide", {
direction: "up"
}, 1000);
}
});
#dccontainer {
position: absolute;
bottom: 0;
width: 300px;
left: 50%;
height: 200px;
margin-left: -150px;
transition: .5s;
overflow: hidden;
}
#dccontainer * {
margin-top: 0;
margin-bottom: 0;
padding-top: 0;
padding-bottom: 0;
font-family: 'Roboto', 'Helvetica', 'Arial', 'sans-serif';
font-weight: bold;
/* font-family: 'Catamaran', 'Roboto', 'Helvetica', 'Arial', 'sans-serif'; */
}
#dcsupporttab {
background-color: #f5f5f5;
color: #434343;
text-align: center;
width: 150px;
padding: 10px;
padding-bottom: 3px;
margin: auto;
border-top-left-radius: 10px;
border-top-right-radius: 10px;
cursor: pointer;
}
#dcsupportcontainer {
background-color: #f5f5f5;
padding-top: 10px;
color: #434343;
display: flex;
flex-direction: column;
justify-content: space-evenly;
align-items: center;
/*height: calc(100% - 43px); */
display: none;
}
.dcbutton {
display: flex;
text-align: center;
background-color: #fff;
border-radius: 10px;
flex-direction: column;
justify-content: center;
align-items: center;
width: 230px;
height: 40px;
}
.dcthelabel {
text-decoration: none;
color: #434343;
text-transform: uppercase;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.nonsolid {
background-color: #f5f5f5;
border-color: #fff;
border-style: solid;
border-width: 3px;
}
#dcmessageus {
text-transform: none;
}
#dcaslnow {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="dccontainer">
<p id="dcsupporttab">Support</p>
<div id="dcsupportcontainer">
<div class="dcbutton" id="dcaslnow">
ASL Now
</div>
<div class="dcbutton" id="dctextchat">
Text Chat
</div>
<div class="dcbutton nonsolid" id="dcmessageus">
Send Us a Message
</div>
<p id="dcvpinfo">Video Chat: (123) 456-7890</p>
</div>
</div>
I've tried various techniques. I've tried toggling with CSS alone using CSS animation and toggleClass, I've tried using slide, and I've tried using slideToggle. I also tried using display: block; instead of using flexbox. Both had the same effect. Researching the internet yielded several possible solutions (which I've tried, but all came out with the same result), and those usually weren't based on an element being fixed at bottom of window. The only one that came closest to what I was looking for was this:
http://atomicrobotdesign.com/blog_media/toggleslide_multiple.html
But strangely, when I attempted to use the same code that used, nothing happened. Clicking did not bring up the menu. I'm at a loss at this point. Where am I going wrong?
This is my latest attempt (using above code): https://codepen.io/doncullen/pen/JjdrxzY
To answer your question Where am I going wrong: you're specifying a fixed height of 200px on #dccontainer. Specifying a fixed height to the container renders the jQuery's slideToggle useless. jQuery's slideToggle animates the height of the given element, and in your case, you're animating #dcsupportcontainer. Even though you're animating the height of #dcsupportcontainer to 0px using slideToggle, the whole support block will still remain 200px in height. This causes makes the whole block not to move down when the #dcsupportcontainer is gone. You can, of course, manually calculate and assign the new bottom value to #dccontainer, but that's a real hassle and really unintuitive.
Not wanting to calculate the bottom value myself, I will not set a height to #dccontainer and just let its height be. It will set its height to all its children's requirements (the default value is auto). Furthermore, instead of using fixed, you used absolute. You should use fixed here as you want the support block to always be visible (even when the user scrolls down); this means that you should position it based on your viewport and not an element (read more about positioning here). I also did minor adjustments on your CSS styles so that it's a tad more concise. One last thing, I suggest that you revisit flexbox here and here to utilise it better.
Here's a working solution:
// First time accessing, hide the support buttons section
$('#dcsupportcontainer').hide()
$("#dcsupporttab").click(function() {
$('#dcsupportcontainer').slideToggle(500)
});
* {
box-sizing: border-box;
margin: 0;
}
body {
min-width: 100vw;
min-height: 100vh;
}
#dccontainer {
position: fixed;
left: 50%;
bottom: 0px;
transform: translateX(-50%);
display: flex;
flex-direction: column;
align-items: center;
width: 50vw;
min-width: 200px;
font-family: 'Roboto', 'Helvetica', 'Arial', 'sans-serif';
}
#dccontainer * {
padding: 7px 20px;
text-align: center;
}
#dcsupporttab {
font-weight: bold;
border-radius: 5px 5px 0 0;
background: #121212;
color: #ffffffee;
cursor: pointer;
}
#dcsupportcontainer {
border: 1px solid #121212;
border-radius: 5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="dccontainer">
<p id="dcsupporttab">Support</p>
<div id="dcsupportcontainer">
<div class="dcbutton" id="dcaslnow">
ASL Now
</div>
<div class="dcbutton" id="dctextchat">
Text Chat
</div>
<div class="dcbutton nonsolid" id="dcmessageus">
Send Us a Message
</div>
<p id="dcvpinfo">Video Chat: (123) 456-7890</p>
</div>
</div>
Just take the fixed height from your main container #dccontainer, and everything will be fine. You should also remove a few lines of your javascript code to fix everything. That fixed height of dccontainer makes the whole nav to stand 200px up from the bottom of your page and that makes you use more jQuery to fix it at the bottom. Remember that the bottom: 0px will set the bottom of your element at the 0px bottom of its container.
$("#dcsupporttab").click(function() {
$('#dcsupportcontainer').slideToggle(500, function() {
//execute this after slideToggle is done
});
});
#dccontainer {
position: absolute;
bottom: 0px;
width: 300px;
left: 50%;
margin-left: -150px;
transition: .5s;
overflow: hidden;
}
#dccontainer * {
margin-top: 0;
margin-bottom: 0;
padding-top: 0;
padding-bottom: 0;
font-family: 'Roboto', 'Helvetica', 'Arial', 'sans-serif';
font-weight: bold;
/* font-family: 'Catamaran', 'Roboto', 'Helvetica', 'Arial', 'sans-serif'; */
}
#dcsupporttab {
background-color: #f5f5f5;
color: #434343;
text-align: center;
width: 150px;
padding: 10px;
padding-bottom: 3px;
margin: auto;
border-top-left-radius: 10px;
border-top-right-radius: 10px;
cursor: pointer;
}
#dcsupportcontainer {
background-color: #f5f5f5;
padding-top: 10px;
color: #434343;
display: flex;
flex-direction: column;
justify-content: space-evenly;
align-items: center;
/*height: calc(100% - 43px); */
display: none;
}
.dcbutton {
display: flex;
text-align: center;
background-color: #fff;
border-radius: 10px;
flex-direction: column;
justify-content: center;
align-items: center;
width: 230px;
height: 40px;
}
.dcthelabel {
text-decoration: none;
color: #434343;
text-transform: uppercase;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.nonsolid {
background-color: #f5f5f5;
border-color: #fff;
border-style: solid;
border-width: 3px;
}
#dcmessageus {
text-transform: none;
}
#dcaslnow {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="dccontainer">
<p id="dcsupporttab">Support</p>
<div id="dcsupportcontainer">
<div class="dcbutton" id="dcaslnow">
ASL Now
</div>
<div class="dcbutton" id="dctextchat">
Text Chat
</div>
<div class="dcbutton nonsolid" id="dcmessageus">
Send Us a Message
</div>
<p id="dcvpinfo">Video Chat: (123) 456-7890</p>
</div>
</div>

Categories