Select Multiple Elements with Query Selector Alll - JavaScript - javascript

I have an intersectionObserver on a box that changes color when it comes into the viewport which all works fine.
I'm trying to apply this to multiple boxes though, and when I change the the getElementsById to querySelectorAll (line 13 of the JS) it doesn't play ball.
Does anyone know what I'm doing wrong here? I don't think the problem is with the intersectionObserver, I think it's with the selector. It's driving me mad.
Codepen: https://codepen.io/emilychews/pen/RMWRPZ
window.addEventListener("load", function(){
var iO = "IntersectionObserver" in window; /* true if supported */
if (iO) {
const config = {
root: null, // sets the framing element to the viewport
rootMargin: '400px 0px 0px 0px', // should remove the animation 400px after leaving the viewport
threshold: .5
};
const box = document.getElementById('box1');
// const box = document.querySelectorAll('.box');
let observer = new IntersectionObserver(function(entries) {
entries.forEach(function(item) {
if (item.intersectionRatio > .5) {
item.target.classList.add("active");
} else {
item.target.classList.remove("active");
}
});
}, config);
observer.observe(box);
} // end of if(iO)
}); // end of load event
body {
font-family: arial;
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
height: 250vh;
}
.box {
margin: 1rem;
width: 100px;
height: 100px;
background: blue;
opacity: 1;
transition: .5s all;
display: flex;
justify-content: center;
align-items: center;
color: #fff;
}
.active {
background: red;
opacity: 1;
}
<div id="box1" class="box">Box 1</div>
<div id="box2" class="box">Box 2</div>

querySelectorAll returns an array of nodes, getElementById returns a single dom object. observer.observe needs a dom object as a parameter, so a solution to that could be
const box = document.getElementsByClassName('box');
box.forEach(function(item){
observer.observe(item);
});

Related

Is the child element visible in the parent

I am making a comment system, there is a certain block in which there are others (messages) how, when scrolling through these messages, to find out whether the user sees one particular one (for example, with the identifier x) or not,
HTML:
<div class="parent">
<div class="msg" id="a"></div>
<div class="msg" id="b"></div>
<div class="msg" id="c"></div>
<div class="msg" id="x"></div>
</div>
CSS:
.parent {
width: 100%;
height: 100%;
height: 89%;
overflow: scroll;
padding-top: 10px;
padding-bottom: 70px;
}
.msg {
width: 98%;
height: 500px;
padding: 10px;
position: relative;
margin: 0 auto;
border: 2px hsl(174deg 72% 41%) solid;
color: hsl(174deg 72% 41%);
border-radius: 20px
px
;
margin-top: 10px;
}
JS:
document.querySelector(".parent").onscroll = () => {
//what to write here?
}
That is: if the message has become visible in the general block, then paint it in yellow
I tried different options: getComputedStyle, and getBoundingClientRect, and offset, but none of this helped me, they constantly say that the message is visible
BUT:
getBoundingClientRect doesn't work, I don't need to check if it's visible in the whole window, I need to check if it's ONLY visible in a div element
WHEN SCROLLING A PARENT ELEMENT
As suggested in the comments by other user, what you are looking for is the Intersection Observer API
https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API
Here's a demo trying to apply the concept to your scenario. It's not very well factored but clearly shows a document containing both your .msg container (.parent) styled as overflow-y: scroll; and other elements before and after taking space on the viewport.
All .msg elements will be observed for intersection in the visible space of their parent so that every time each one of them will be visible, its id will be printed on console. Plus there's an added trigger callback that will be invoked in the event described above, that will check for a condition (for example if the element currently became visible has id == 'c') to perform an action.
//this will be called everytime a target element being observer became visible,
//and will check a condition before performing an action (if the element.id === c for example)
const trigger = (element)=>{
if (element.id === 'c')
console.log('condition met! element with id == c was reached.');
}
const observerOptions = {
root: null,
rootMargin: '0px',
threshold: 0
};
//gets called everytime any of the targets appears on the viewport
const observerCallback = (entries, observer) => {
//for each of the observed entries
entries.forEach(entry => {
//console logs the element id currently intersecting the viewport
if (entry.isIntersecting){
console.log(entry.target.id);
trigger(entry.target);
}
});
};
//sets up an observer...
//calling the observerCallback when the observed targets will be intersecting the viewport
const observer = new IntersectionObserver(observerCallback, observerOptions);
//the targets the observer will be observing for (each .msg children inside the .parent element)
const observerTargets = document.querySelectorAll('.parent > .msg');
observerTargets.forEach(target => observer.observe(target));
.other-content{
display: block;
outline: dashed 3px gray;
height: 100px;
display: flex;
align-items: center;
justify-content: center;
font-family: arial;
color: gray;
}
.parent {
display: block;
margin: 10px 10px;
height: 120px;
overflow-y: scroll;
outline: solid 1px gray;
}
.msg {
position: relative;
display: block;
width: 100%;
height: 200px;
padding: 0;
margin: 10px 0;
box-sizing: border-box;
border: solid 2px hsl(174deg 72% 41%);
border-radius: 10px;
}
.msg::before {
position: absolute;
content: 'id: ' attr(id);
top: 50%;
left: 50%;
border-radius: 1rem;
padding: 1rem 1rem;
background: gray;
font-size: 2rem;
font-weight: 600;
color: white;
}
<div class="other-content">
before..
</div>
<div class="parent">
<div class="msg" id="a"></div>
<div class="msg" id="b"></div>
<div class="msg" id="c"></div>
<div class="msg" id="x"></div>
</div>
<div class="other-content">
..after
</div>

HTMLDivElement resizing inconsistent after WebpackDevServer build

I have a custom web component that I am trying to make which looks like this
But it looks like this after I reload the page
Notice the thin white div at the very bottom of each image.
I notice that I get the desired result (the fist image) immediately following a Webpack build triggered by saving this component's javascript file. Each time I reload the page, the second image is rendered on screen. What causes this behavior? I will attach the pertinent parts of my code below. (The styling for the large yellow and white components is done for privacy)
FeaturedProjectCard.js
const template = document.createElement('template')
template.innerHTML = `
<style>
.bottomDivider {
position: absolute;
bottom: 0;
width: 75%;
height: 1px;
margin: 0;
background-color: white;
}
.container {
position: relative;
width: 1000px;
isolation: isolate;
}
.description {
border-radius: 10px;
padding: 25px;
color: white;
background-color: white;
}
.linksContainer {
display: flex;
}
.linksContainer > a {
width: 20px;
padding: 10px;
color: white;
transition: color 0.5s;
}
.linksContainer > a:first-child {
padding-left: 0;
}
.linksContainer > a:hover {
color: yellow;
}
.projDesc {
width: 50%;
display: flex;
flex-direction: column;
pointer-events: none;
}
.projDesc > * {
width: fit-content;
pointer-events: auto;
}
.projImage {
position: absolute;
top: 50%;
right: 0;
height: 300px;
transform: translateY(-50%);
background-color: yellow;
border-radius: 5px;
z-index: -1;
}
.projImage > img {
height: inherit;
border-radius: inherit;
filter: grayscale(100%);
-webkit-filter: grayscale(100%);
opacity: 0;
transition: opacity 0.5s, filter 0.5s, -webkit-filter 0.5s;
}
.projImage > img:hover {
opacity: 1;
filter: grayscale(0%);
-webkit-filter: grayscale(0%);
}
.projectHeading {
margin: 10px 0;
color: yellow;
font-size: 12pt;
}
.projectName {
display: inline;
margin: 15px 0;
font-size: 21pt;
color: white;
}
.softwareContainer {
margin: 25px 0 10px 0;
color: white;
}
.softwareContainer > span:not(:last-child) {
padding-right: 30px;
}
</style>
<div class="container">
<div class="projDesc">
<span class="projectHeading">Recent Project</span>
<span class="projectName"></span>
<div class="description"></div>
<div class="softwareContainer"></div>
<div class="linksContainer"></div>
</div>
<div class="projImage">
<img>
</div>
<p class="bottomDivider"></p>
</div>
`
class FeaturedProjectCard extends HTMLElement {
constructor() {
super()
//Enable shadow DOM
this.attachShadow({ mode: 'open' })
this.shadowRoot.appendChild(template.content.cloneNode(true))
//Insert project image
this.shadowRoot.querySelector('img').src = this.getAttribute('image')
//Insert project heading
this.shadowRoot.querySelector('.projectName').textContent = this.getAttribute('heading')
//Insert project description
this.shadowRoot.querySelector('.description').innerHTML = //Get description text
//Insert software array
const softwareItems = //Get items
if(softwareItems) {
const softwareContainer = this.shadowRoot.querySelector('.softwareContainer')
for(let i = 0; i < softwareItems.length; i++)
softwareContainer.innerHTML += `<span>${softwareItems[i].textContent}</span>`
}
//Insert link array
const links = //Get links
if(links) {
const linksContainer = this.shadowRoot.querySelector('.linksContainer')
for(let i = 0; i < links.length; i++) {
linksContainer.innerHTML += `<a target="_blank" href="${links[i].getAttribute('target')}">${links[i].innerHTML}</a>`
}
}
//Handle reverse attribute
if(this.hasAttribute('reversed')) {
this.shadowRoot.querySelector('.bottomDivider').style.right = 0;
this.shadowRoot.lastElementChild.style.height = `${this.shadowRoot.lastElementChild.offsetHeight}px`
const projDesc = this.shadowRoot.querySelector('.projDesc')
const projImage = this.shadowRoot.querySelector('.projImage')
const softwareItems = Array.from(this.shadowRoot.querySelectorAll('.softwareContainer > span'))
projDesc.style.position = 'absolute'
projDesc.style.right = '0'
projDesc.style.left = 'auto'
projImage.style.left = '0'
projImage.style.right = 'auto'
projDesc.style.alignItems = 'flex-end'
softwareItems.splice(0, 1)[0].style.padding = '0'
const padding = getComputedStyle(softwareItems[0]).getPropertyValue('padding-right')
softwareItems.forEach(item => {
item.style.paddingLeft = padding
item.style.paddingRight = '0'
})
}
//Clear markup
this.innerHTML = null
}
}
window.customElements.define('featured-project-card', FeaturedProjectCard)
I use these component in HTML with the following syntax.
<featured-project-card class="" reversed image="/something.png" heading="Heading">
I think that the root cause of this behavior is the inclusion of the optional 'reversed' attribute. The other components that don't use this attribute are not affected by this issue since div.projDesc has position: static for those instances. This allows the div.container to resize. These images show the only component where this attribute is used. I will end this post with one final image of a component without the 'reversed' attribute for reference. In essence, I achieve the reverse effect by setting the div.projDesc properties position, right, and left to absolute, 0, and auto respectively. Consequently, I had to set the div.container height equal to what it was prior to these changes. Otherwise the element would not size correcly since position: absolute is being used on the only child with position: static
I used a ResizeObserver to see if the div.projDesc was resizing itself more than once and indeed it was. To wrap up, the 'reversed' div.projDesc is resizing itself strangely (likely because of how the 'reverse' attribute is handled) as opposed to non 'reversed' elements. I am aware that there may be an easier way to solve this problem and I am open to suggestions, however, I would like to pin down the source of this behavior in hopes of gaining a better understanding of the nuances of HTML, CSS, & JS. I am more than happy to clarify myself for anyone that is willing to lend a hand. Thank you in advance!
Non reversed component

3 column fluid layout with expanding middle div based on panel positions

Apologies for the not-super-descriptive title, I'm having a hard time verbalizing the problem, so let me try again in more detail.
I am using flexbox to create a 3 column layout, where I'm looking to have the middle column expand when either (or both) of the left / right columns (menu panels) are collapsed.
Here's a screen shot of the problem I'm experiencing.
https://www.dropbox.com/s/d9mcg7q71hwogog/example.jpg?dl=0
When the panels are open (expanded) all three columns fill the width of the screen. This is good. However, when either of the two sidepanels is animated (collapsed), the center column does not expand to fill in the additional space. This is not good.
I'm not sure if it has to do with the fact that I'm using translateX to toggle the left / right panels and this is a just a theory, but perhaps the center column doesn't realize that the left / right columns have shifted position, so it doesn't know there's more space to fill?
Code to follow:
CSS:
<style>
body {
background-color: lightslategrey;
}
.red {
background-color: lightcoral;
}
.green {
background-color: lightgreen;
}
.grey {
background-color: lightslategray;
}
* {
box-sizing: border-box;
}
.ls-toggle, .rs-toggle {
//position: fixed;
z-index: 1;
cursor: pointer;
transition: 0.5s;
}
#left-sidebar, #right-sidebar {
width: 250px;
height: 100vh;
transition: 0.5s;
}
#left-sidebar.is-closed {
transform: translateX(-80%);
}
#right-sidebar.is-closed {
transform: translateX(80%);
}
.ls-top, .rs-top {
display: flex;
width:100%;
height:35px;
align-items: center;
justify-content: flex-end;
background-color: lightslategrey;
}
.rs-top {
justify-content: flex-start;
}
#mw-content {
width: 100%;
height: 100vh;
}
</style>
HTML:
<div class="d-flex">
<div id="left-sidebar" class="col- red">
<div class='ls-top grey'>
<button class="ls-toggle"><i class="fas fa-angle-left fa-2x"></i></button>
</div>
</div>
<div id="mw-content" class="col green">
<h3> Main Window Content.</h3>
</div>
<div id="right-sidebar" class="col- red">
<div class='rs-top grey'>
<button class="rs-toggle"><i class="fas fa-angle-right fa-2x"></i></button>
</div>
</div>
</div>
JS:
$(document).ready(function () {
var lsToggleBtn = document.querySelector('.ls-toggle');
var lsSidebar = document.querySelector('#left-sidebar');
var rsToggleBtn = document.querySelector('.rs-toggle');
var rsSidebar = document.querySelector('#right-sidebar');
lsToggleBtn.addEventListener('click', function () {
lsToggleBtn.classList.toggle('is-closed');
lsSidebar.classList.toggle('is-closed');
});
rsToggleBtn.addEventListener('click', function () {
rsToggleBtn.classList.toggle('is-closed');
rsSidebar.classList.toggle('is-closed');
});
});
Things I've tried:
Adding flex: 1 1 auto to main content container (mw-content).
Adding flex: 0 to l/r sidebar containers & flex: 1 1 auto to main content container
Setting width to 100% on main content container
Attempting to use translateX on main content container & setting new width when clicking left sidebar
Obviously none of those ideas worked, and I freely admit I'm not the greatest with flexbox, so I'm sure I'm just missing something basic, but I'd appreciate any suggestions you fine folks might have. :)
You need to play with "position: absolute" and add two more classList.toggle functions
$(document).ready(function () {
var mwContent = document.querySelector('#mw-content'); // !!
var lsToggleBtn = document.querySelector('.ls-toggle');
var lsSidebar = document.querySelector('#left-sidebar');
var rsToggleBtn = document.querySelector('.rs-toggle');
var rsSidebar = document.querySelector('#right-sidebar');
lsToggleBtn.addEventListener('click', function () {
lsToggleBtn.classList.toggle('is-closed');
lsSidebar.classList.toggle('is-closed');
mwContent.classList.toggle('ls-pos'); // here
});
rsToggleBtn.addEventListener('click', function () {
rsToggleBtn.classList.toggle('is-closed');
rsSidebar.classList.toggle('is-closed');
mwContent.classList.toggle('rs-pos'); // here
});
});
body {
background-color: lightslategrey;
margin: 0;
overflow: hidden;
}
.red {
background-color: lightcoral;
}
.green {
background-color: lightgreen;
}
.grey {
background-color: lightslategray;
}
* {
box-sizing: border-box;
}
.d-flex {
display: flex;
position: relative;
}
.ls-toggle,
.rs-toggle {
cursor: pointer;
transition: 0.5s;
}
#left-sidebar {
position: absolute;
left: 0;
width: 250px;
height: 100vh;
transition: 0.5s;
}
#right-sidebar {
position: absolute;
right: 0;
width: 250px;
height: 100vh;
transition: 0.5s;
}
#left-sidebar.is-closed {
transform: translateX(-80%);
}
#right-sidebar.is-closed {
transform: translateX(80%);
}
.ls-top,
.rs-top {
display: flex;
width: 100%;
height: 35px;
align-items: center;
justify-content: flex-end;
background-color: lightslategrey;
}
.rs-top {
justify-content: flex-start;
}
#mw-content {
position: absolute;
right: 250px;
left: 250px;
height: 100vh;
transition: 0.5s;
}
.ls-pos {
left: 50px !important;
transition: 0.5s;
}
.rs-pos {
right: 50px !important;
transition: 0.5s;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="d-flex">
<div id="left-sidebar" class="col red">
<div class='ls-top grey'>
<button class="ls-toggle"><i class="fas fa-angle-left fa-2x"></i></button>
</div>
</div>
<div id="mw-content" class="col green">
<h3> Main Window Content.</h3>
</div>
<div id="right-sidebar" class="col red">
<div class='rs-top grey'>
<button class="rs-toggle"><i class="fas fa-angle-right fa-2x"></i></button>
</div>
</div>
</div>
Here is an example of how you can achieve this using vanilla javascript.
Two functions, one to track the collapsing of section elements and resize the middle section. It checks click and adds the elements (sections) id to an array, a conditional checks the array and if the array includes the two outer sections id, we resize the middle section using style.transform => scale(). The second function resets the collapsible elements.
More info found in code snippit.
let clicked = [];
const middle = document.querySelector('#sect2')
let section = document.querySelectorAll('.sect')
let reset = document.querySelector('#reset')
// function
const resizeOnCollapse = (els) => {
// loop over the three sections
els.forEach(sect => {
// do not allow the middle section to be collapsed
if (sect.id !== 'sect2') {
// eventlistener to check a click on the outer sections
sect.addEventListener('click', (e) => {
// push the clicked elements into an array
clicked.push(e.target.id)
// set the event targets width to 0
// essentially collapsing it from view
e.target.style.width = '0px';
// conditional that checks if the array
// includes the two outer sections
if (clicked.includes('sect1') && clicked.includes('sect3')) {
// resize the middle section using
// transform: scale()
middle.style.transform = 'scale(1.2)'
// transition animation on the transform
middle.style.transition = 'transform .5s ease-out'
}
})
}
})
}
// function to reset the elements and reset the array
const resetEls = (el, section) => {
// eventlistener on click
el.addEventListener('click', () => {
// reset the array
clicked = [];
// loop over the sections
section.forEach((sect) => {
// reset the width essentially uncollapsing the sections
sect.style.width = '30vw';
// reset the middle transform rule, scale() to 1
sect.style.transform = 'scale(1)';
})
})
}
// call the functions
resetEls(reset, section)
resizeOnCollapse(section)
#main {
display: flex;
justify-content: space-around;
}
.sect {
width: 30vw;
height: 80vh;
}
#sect1 {
background-color: red;
}
#sect2 {
background-color: blue;
}
#sect3 {
background-color: green;
}
<button id="reset">reset</button>
<div id="main">
<div id="sect1" class="sect">
</div>
<div id="sect2" class="sect">
</div>
<div id="sect3" class="sect">
</div>
</div>

Change a forEach() method to a For Loop to use with IntersectionObserver - Javascript

I have the following IntersectionObserver code that is working as a scroll trigger for animations on a site that all works OK.
However, I would like to switch the forEach() method that works as the call for the IntersectionObserver to a for loop, but I can't get this to work.
I'm sure that this can be done, but it's driving me a bit crazy.
The reason for wanting this is because I'm using a polyfill so that IntersectionObserver works in older versions of IE and Edge, but of course the forEach() method doesn't work in these browsers.
I've commented out my attempt at the loop at the bottom of the code.
Any help would be amazing.
Codepen: https://codepen.io/emilychews/pen/xJaZay
window.addEventListener("load", function(){
var iO = "IntersectionObserver" in window; /* true if supported */
var box = document.querySelectorAll('.box');
if (iO) {
const config = {
root: null, // sets the framing element to the viewport
rootMargin: '0px',
threshold: .5
};
let observer = new IntersectionObserver(function(entries) {
entries.forEach(function(item) {
if (item.intersectionRatio > .5) {
item.target.classList.add("active");
} else {
item.target.classList.remove("active");
}
});
}, config);
box.forEach(function(item){
observer.observe(item);
});
// for (i = 0; i < box.length; i++) {
// observer[i].observe(item);
// }
} // end of if(iO)
}); // end of load event
body {
font-family: arial;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 280vh;
}
.box {
position: relative;
margin: 1rem 0;
width: 100px;
height: 100px;
background: blue;
opacity: 1;
transition: .5s all;
display: flex;
justify-content: center;
align-items: center;
color: #fff;
}
#box1{
margin-bottom: 100px;
}
.active {
background: red;
opacity: 1;
}
<div id="box1" class="box">Box 1</div>
<div id="box2" class="box">Box 2</div>
You have one observer but you're applying an index on it. As you're iterating over the boxes, your index accessor should be on box.
for (i = 0; i < box.length; i++) {
observer.observe(box[i]);
}
This should work, it's untested though.

CSS/JS: split words with horizontal line in responsive design

What would be the best way to split a word in the middle (or after a specific amount of characters or syllables) and join both "word-parts" with a line. Basically imagine a very long flexible underscore.
The goal is to have "word___part" always 100% of the parent container.
Meaning it should work fully responsive when scaling down or up the browser-window.
span:first-child {
float:left;
display:inline-block;
}
span.underscore {
}
span:last-child {
float:right;
display:inline-block;
}
<span>Auto</span><span class="underscore"></span><span>mation</span>
How would you approach that? Flexbox?
Additionally the meta-goal would even be to set the word that is split apart with a dynamic-cms. Meaning the word "Automation" comes from a backend.
You can use :after pseudo-element on first span element and set align-items: flex-end; to align line at bottom of spans.
div {
width: 70%;
display: flex;
}
span:first-child {
display: flex;
align-items: flex-end;
flex: 1;
}
span:first-child:after {
content: '';
height: 1px;
background: black;
flex: 1;
}
<div>
<span>Auto</span><span>mation</span>
</div>
<div>
<span>Lorem ipsum dolor </span><span>sit.</span>
</div>
You can also use js to split string at specific word and wrap each part in span elements.
function modify(selector, word) {
var el = document.querySelector(selector);
var text = el.textContent;
var i = text.indexOf(word)
if (i != -1) {
var arr = [text.substring(0, i), text.substring(i)]
el.innerHTML = arr.map(e => '<span>' + e + '</span>').join('');
}
}
modify('.e1', 'mation')
modify('.e2', 'sit')
div {
width: 70%;
display: flex;
}
span:first-child {
display: flex;
align-items: flex-end;
flex: 1;
}
span:first-child:after {
content: '';
height: 1px;
background: black;
flex: 1;
}
<div class="e1">Automation</div>
<div class="e2">Lorem ipsum dolor sit.</div>
Apply border-bottom to .underscore along with flex-grow: 1, then adjust height and margins to fit.
.wrapper {
display: flex;
}
span.underscore {
border-bottom: 2px solid black;
flex-grow: 1;
height: 0.5em;
margin: 0 5px;
}
<div class="wrapper">
<span>Auto</span><span class="underscore"></span><span>mation</span>
</div>
You can even use a dotted border instead of solid to simulate ellipses.
A pretty simple way:
<div>
<span class="left">Auto</span>
<span class="underscore"></span>
<span class="right">mation</span>
</div>
div {
display: flex;
}
.underscore {
width: 100%;
border-bottom: 1px solid #000;
margin: 0 5px;
}
https://codepen.io/anon/pen/XaddqO
In case if background-color behind text element is a solid color:
Create background-image with linear-gradient() on parent.
Override background-color on child elements.
Working Demo:
.text {
background: linear-gradient(to top, transparent 5px, black 5px,
black 7px, transparent 7px);
justify-content: space-between;
display: flex;
}
.text span {
background: #fff;
padding: 0 5px;
}
<div class="text">
<span>Auto</span>
<span>mation</span>
</div>
The answers are good but you said Additionally the meta-goal would even be to set the word that is split apart with a dynamic-cms. Meaning the word "Automation" comes from a backend.
So yiu can use the getword() method to get the word from backend and separate it into two using javascript
You can try to run the snippet and see the output. Then change the string returned by the getword() method and run again.
var container = document.getElementById('slit-container');
var word = getWord();
var wordPartOne = word.substring(0, 4);
var wordPartTwo = word.substring(4, word.lenght);
var data = "<span>"+wordPartOne+"</span> <span>"+wordPartTwo+"</span>";
container.innerHTML = data;
function getWord(){
//Query your backend to get the word
//for test purpose I will just return a string
return "Automation"
}
div {
width: 70%;
display: flex;
}
span:first-child {
display: flex;
align-items: flex-end;
flex: 1;
}
span:first-child:after {
content: '';
height: 1px;
background: black;
flex: 1;
}
<div id="slit-container">
</div>

Categories

Resources