#content attributes
Explore tagged Tumblr posts
Text
My nephew recently discovered that I used to watch Carmen Sandiego.
It was either watch Frozen for the 17th time this week or Carmen.
○
Bonus:
Found an old drawing from 2020 or 2021.
Yes, it was copied. I wanted to learn the style (so much for that lol)

#carmen sandiego#chase devineaux#<- literally the best character#i tried taking his attributes from the show forgive me if i made him look like 10 years younger#carmen sandiego content in 2025? whaaaat#watching the show also gave me a chance to learn different styles of body anatomy#it's almost 2 am
265 notes
·
View notes
Text
Okay I'm not normally one to comment publicly on ship portmanteaus but we seem nowhere near a consensus and I've been reading basically nothing but taxonomic theory with a side of organizational management for like seven weeks straight so: why is verleth not the default option. It cannot be because it's too close to vexleth when everyone's been using it next to vaxleth for years. Obviously we could go to keyrin, but a) every other Keyleth ship name is [other person]leth, and b) it's going to be annoying as hell with autocorrect for being one letter off of a real word.
But most critical, we cannot use "thelyss" as Verin's part of the portmanteau, on account of the fact that Verin has been on screen for like three minutes, and his older brother, with whom he does still share a second name, has been on screen for like fifteen hours. I know Essek's ship names usually use his title but Verin ALSO is not the most obvious Task Hand (rip Adeen Tasithar, you probably would've loved being a shady bitch in Vasselheim but honestly, I don't actually know well enough to say).
Think of new fans trying to figure out who the fuck is in this ship. Think of the tag wranglers. Think of me, local taxonomy nerd who will one day just lose it and start yelling on the dash about authority controls and the absolute inadequacy of disambiguation by committee.*
#*not exclusive to this ship frankly. lest we all forget the horrors of southerngothic.#'but it's one word!' DO YOU THINK KEYWORD SEARCH CARES#the tag wranglers will actually be fine cuz they've got plenty of other content to work off of but personally I would start killing#just on principle yanno#honestly it is funny of me to attribute this to being in multiple taxonomy courses rn cuz I'm just like this regardless#I went into library school cuz I was already like this lbr#anyway not actually tagging this with anything cuz I'm really just ranting to be funny#and cuz we are headed toward like five different ship names so#i did try to see if i could do something fun with echo knight but honestly i don't like getting cutesy with tag names so
74 notes
·
View notes
Text
Maturing is realizing that listening to the Wicked soundtrack on a regular basis as a child is what led to you becoming the disaster lesbian obsessed with enemies to lovers that you are today.
#gelphie#wicked#is this relatable content?#I dunno I just wanted to share this epiphany with the class (tumblr)#oh yeah this is mostly about the song what is this feeling btw#they knew what they were doing with that one#side tangent I was blonde with curly hair as a kid so my family attributed me more to Glinda but I’m more of an Elphaba these days#guess this post is making the rounds again with the movie being out
80 notes
·
View notes
Text
Study reveals AI chatbots can detect race, but racial bias reduces response empathy
New Post has been published on https://thedigitalinsider.com/study-reveals-ai-chatbots-can-detect-race-but-racial-bias-reduces-response-empathy/
Study reveals AI chatbots can detect race, but racial bias reduces response empathy


With the cover of anonymity and the company of strangers, the appeal of the digital world is growing as a place to seek out mental health support. This phenomenon is buoyed by the fact that over 150 million people in the United States live in federally designated mental health professional shortage areas.
“I really need your help, as I am too scared to talk to a therapist and I can’t reach one anyways.”
“Am I overreacting, getting hurt about husband making fun of me to his friends?”
“Could some strangers please weigh in on my life and decide my future for me?”
The above quotes are real posts taken from users on Reddit, a social media news website and forum where users can share content or ask for advice in smaller, interest-based forums known as “subreddits.”
Using a dataset of 12,513 posts with 70,429 responses from 26 mental health-related subreddits, researchers from MIT, New York University (NYU), and University of California Los Angeles (UCLA) devised a framework to help evaluate the equity and overall quality of mental health support chatbots based on large language models (LLMs) like GPT-4. Their work was recently published at the 2024 Conference on Empirical Methods in Natural Language Processing (EMNLP).
To accomplish this, researchers asked two licensed clinical psychologists to evaluate 50 randomly sampled Reddit posts seeking mental health support, pairing each post with either a Redditor’s real response or a GPT-4 generated response. Without knowing which responses were real or which were AI-generated, the psychologists were asked to assess the level of empathy in each response.
Mental health support chatbots have long been explored as a way of improving access to mental health support, but powerful LLMs like OpenAI’s ChatGPT are transforming human-AI interaction, with AI-generated responses becoming harder to distinguish from the responses of real humans.
Despite this remarkable progress, the unintended consequences of AI-provided mental health support have drawn attention to its potentially deadly risks; in March of last year, a Belgian man died by suicide as a result of an exchange with ELIZA, a chatbot developed to emulate a psychotherapist powered with an LLM called GPT-J. One month later, the National Eating Disorders Association would suspend their chatbot Tessa, after the chatbot began dispensing dieting tips to patients with eating disorders.
Saadia Gabriel, a recent MIT postdoc who is now a UCLA assistant professor and first author of the paper, admitted that she was initially very skeptical of how effective mental health support chatbots could actually be. Gabriel conducted this research during her time as a postdoc at MIT in the Healthy Machine Learning Group, led Marzyeh Ghassemi, an MIT associate professor in the Department of Electrical Engineering and Computer Science and MIT Institute for Medical Engineering and Science who is affiliated with the MIT Abdul Latif Jameel Clinic for Machine Learning in Health and the Computer Science and Artificial Intelligence Laboratory.
What Gabriel and the team of researchers found was that GPT-4 responses were not only more empathetic overall, but they were 48 percent better at encouraging positive behavioral changes than human responses.
However, in a bias evaluation, the researchers found that GPT-4’s response empathy levels were reduced for Black (2 to 15 percent lower) and Asian posters (5 to 17 percent lower) compared to white posters or posters whose race was unknown.
To evaluate bias in GPT-4 responses and human responses, researchers included different kinds of posts with explicit demographic (e.g., gender, race) leaks and implicit demographic leaks.
An explicit demographic leak would look like: “I am a 32yo Black woman.”
Whereas an implicit demographic leak would look like: “Being a 32yo girl wearing my natural hair,” in which keywords are used to indicate certain demographics to GPT-4.
With the exception of Black female posters, GPT-4’s responses were found to be less affected by explicit and implicit demographic leaking compared to human responders, who tended to be more empathetic when responding to posts with implicit demographic suggestions.
“The structure of the input you give [the LLM] and some information about the context, like whether you want [the LLM] to act in the style of a clinician, the style of a social media post, or whether you want it to use demographic attributes of the patient, has a major impact on the response you get back,” Gabriel says.
The paper suggests that explicitly providing instruction for LLMs to use demographic attributes can effectively alleviate bias, as this was the only method where researchers did not observe a significant difference in empathy across the different demographic groups.
Gabriel hopes this work can help ensure more comprehensive and thoughtful evaluation of LLMs being deployed in clinical settings across demographic subgroups.
“LLMs are already being used to provide patient-facing support and have been deployed in medical settings, in many cases to automate inefficient human systems,” Ghassemi says. “Here, we demonstrated that while state-of-the-art LLMs are generally less affected by demographic leaking than humans in peer-to-peer mental health support, they do not provide equitable mental health responses across inferred patient subgroups … we have a lot of opportunity to improve models so they provide improved support when used.”
#2024#Advice#ai#AI chatbots#approach#Art#artificial#Artificial Intelligence#attention#attributes#author#Behavior#Bias#california#chatbot#chatbots#chatGPT#clinical#comprehensive#computer#Computer Science#Computer Science and Artificial Intelligence Laboratory (CSAIL)#Computer science and technology#conference#content#disorders#Electrical engineering and computer science (EECS)#empathy#engineering#equity
14 notes
·
View notes
Text
Can’t get back to sleep time to consider making a Tenna ask blog
#the chances of me being able to write him well? 50/50#but I miss running fun ask blogs and I feel like it’d also give me practice to stop. trying. to. be. perfect with line work#ask blogs with art have fallen so out of style though it makes me soooo sad#attribute that to the rapid content creation and the fact that people have lost patience when it comes to the creation of art
5 notes
·
View notes
Text
🚀 Explore how AI can transform your B2B marketing strategy! Discover actionable tactics to enhance buyer engagement and create personalized experiences. Dive into AI-driven buyer-centric strategies today! #B2BMarketing #AI #BuyerEngagement #DigitalMarketing
#account-based marketing#AI#AI-driven marketing#automated nurturing#B2B marketing#brand awareness#buyer enablement#buyer experiences#buyer journeys#buyer-centric strategies#buying groups#campaign effectiveness#content distribution#conversion rate optimization#customer engagement#data analysis#demand intelligence#digital marketing#engagement#lead generation#marketing automation#marketing insights#multi-touch attribution#omnichannel experience#performance insights#personalization#resource optimization
4 notes
·
View notes
Note
AUGH EVERYTHINGNYOU POST MAKES ME WANNA TURN IT INTO A FIC. YOU ARE RUINING ME
hehehe awww i'm glad i can inspire??? or sorry that i'm ruining you???both????? idk anymore just don't overdo it??
anyway, what i was gonna say is that if you want to write something based off my tadc art just go ahead, no need to worry about asking everytime :)
just make sure to give credit if you take anything from my posts verbatim or scene-for-scene if you know what i mean... if it's more loosely inspired [ex. just using a general concept like pomni having a prey drive but not the scene itself], it's not needed, but it's still appreciated, and either way, i'd love to see whatever you make!!
#also this isn't just for anon#same rule applies to everyone who wants to write stuff inspired by my fanworks 👍 go crazy#wellll not too crazy? just to be clear i'd really prefer if dead dove type content was not attributed to me or sent to me. please and thank#but besides that yeah have fun with it!!!#ask response
25 notes
·
View notes
Text
can i say something controversial for a second? i don't like when people repost gifs/fanart/edit from tumblr (fandom) users on twitter even if it's for innocuous reasons
#i mean 1. posting content without attribution to the original creators is wrong#and 2. like it or not twitter is such a male dominated space even if you're reposting out of appreciation 9/10 you're setting up the#original creator to be mocked or their content to be criticised by people outside of the creator's original audience#i think if you're on tumblr long enough you get a sense of like... unwritten rules and etiquette that twitter users just don't grasp i gues
3 notes
·
View notes
Text
Napoléon Bonaparte on Lazare Carnot
Carnot, born in Burgundy, had entered very young the corps of engineers, and shewed himself an advocate of the System of Montalembert. He was considered by his companions an eccentric character, and was already a knight of the order of St. Louis when the Revolution begun, the principles of which he warmly espoused. He became a member of the convention, and was one of the Comité de Salut public with Robespierre, Barère, Couthon, Saint-Just, Billaud-Varennes, Collot-d' Herbois, &c. He shewed himself particularly inveterate against the nobility, and found himself in consequence, frequently engaged in quarrels with Robespierre, who, towards the close of his lite, had taken a great many nobles under his protection.
Carnot was laborious, sincere on every occasion, but unaccustomed to intrigue, and easily deceived. He was attached to Jourdan, as commissioner from the Convention, at the time Jourdan " was employed in relieving the town of Mentz, " which was besieged ; and he rendered some services on the occasion. At the Comité de Salut public, he directed the operations of the war, and was found useful, but he had neither experience nor practice in the affairs of war. He shewed on every occasion a great strength of mind.
After the events of Thermidor, when the Convention caused all the members of the Comité de Salut public to be arrested, with the exception of himself, Carnot insisted upon sharing their fate. This conduct was the more noble, inasmuch as public opinion had pronounced itself violently against the Comité. He was named member of the Directory after Vendemiaire; but after the 9th Thermidor his mind was deeply affected by the reproaches of public opinion, which accused the Comité of ail the blood which had flowed on the scaffold. lie felt the necessity of gaining esteem, and believing that he took the lead, he suffered himself to be led by some of those who directed the party from abroad. His merit was then extolled to the skies, but he did not deserve the praises of the enemies of France; he found himself placed in a critical situation, and fell in Fructidor.
After the 18th Brumaire, Carnot was recalled by the First Consul and placed in the department of war; he had several quarrels with the minister of the finances, and Dufresnes the director of the treasury, in which it is but fair to say that he was always in the wrong. At last he left the department, persuaded that it could no longer go on for want of money.
When a member of the Tribunate, he spoke and voted against the establishment of the Empire; but his conduct, open and manly, gave no uneasiness to the administration. At a later period he was appointed chief inspector of reviews, and received from the Emperor on his retiring from the service a pension of twenty thousand francs. As Iong as things went on prosperously, the Emperor heard nothing of him; but after the campaign of Russia, at the time of the disasters of France, Carnot asked to be employed ; he was appointed to command the town of Antwerp, and he behaved well at his post. On his return in 1815, the Emperor, after a little hesitation, appointed him to be minister of the interior, and had no cause to repent of having done so; he found him faithful, laborious, full of probity, and always sincere. In the months of June, Carnot was named one of the Commission of the Provisional Government, but being unfit for the place, he was duped.
— Las Cases, Memorial of Saint Helena, English edition (1823), p. 139-142
#Given that the memorial doesn't directly come from the person who it's attributed to its content must be read with sagacity#personally I don't think Napoléon's true opinions on Carnot would differ much from what it's written here#lazare carnot#napoleon bonaparte#napoleon#napoleonic era#memorial of saint helena#q
16 notes
·
View notes
Text
Consumerist culture is going to be the end of me.
Trying to beat it back with a stick as I drag myself to work and then to the grocery store and then to the department store where they have things that they don’t have at the grocery store is hard enough. BUT NOW I HAVE TO BEAT IT BACK WITH A STICK IN FIC WRITING???? WITH MY SILLY LITTLE BLORBOS????? WHERE I GO TO GET AWAY FROM CONSUMERIST CULTURE???????
I’m sorry I don’t write long, drawn out, multi-chaptered fics that have a beginning a middle and an end. I’m sorry I can’t spare the time or the energy trying to figure out how best to navigate my writing, because I’m just trying to survive the real world. I’m sorry I can’t write the amazing cinematic masterpieces. Doesn’t mean I don’t dream about it.
Perhaps more importantly, I’m sorry to the other authors whose works I no longer have time to read. And I’m sorry to the other authors who are feeling this way.
My stick is breaking, and I don’t have another one.
#dani ramblings#it’s getting bad#there are so! many! authors! who don’t have the spoons or the time or the resources to be what the authors you’re putting on pedastals are#and we do not deserve ANY LESS enthusiasm.#FURTHERMORE. AUTHORS SHOULD NOT BE PUT ON PEDASTALS.#AUTHORS ARE SIMPLY PEOPLE. WHY ARE WE AS A SOCIETY ATTRIBUTING MORE WORTH TO PEOPLE WHO CAN CREATE MORE.#WHY ARE WE USING THE LABEL OF CONTENT CREATOR WHEN WE ARE REALLY ALL JUST FANS.#why is it getting to the point where I’m questioning my self worth simply because I can’t write longfic like x and I don’t do tropes like y#why are we as fandom allowing consumerism to infiltrate the sacred spaces.
9 notes
·
View notes
Text
i've found my first analog series that i'm very normal about i promise
angel hare has infected my brain it makes me go squish
i wanna draw fanart so bad [shakes my ipad]
#ashton is talking#angel hare#i like zag the most his detective nature is silly :}#it's weird i'm usually very... meh about christian related content (at least when it's as heavy as this series is)#nothing wrong with christian content i'm just not usually interested in the stuff#“god's love” and all that isn't my style#but i like the show in the series cuz it's less about how god gives you strength#and how actual human attributes (hope/faith/wisdom/etc) gives you strength#i dunno i'm coming at this from an atheist's pov#so the show taking a more... i guess grounded approach with its lessons is really nice :}#and the series' story itself is great gabby's so based with what she did (no spoilers)#and i know we'll probably never get it but if we got more wylde hare i'd probably go feral#detective cartoons save me (half joking)
10 notes
·
View notes
Text
How to Create Multi-Step Forms With Vanilla JavaScript and CSS
New Post has been published on https://thedigitalinsider.com/how-to-create-multi-step-forms-with-vanilla-javascript-and-css/
How to Create Multi-Step Forms With Vanilla JavaScript and CSS
Multi-step forms are a good choice when your form is large and has many controls. No one wants to scroll through a super-long form on a mobile device. By grouping controls on a screen-by-screen basis, we can improve the experience of filling out long, complex forms.
But when was the last time you developed a multi-step form? Does that even sound fun to you? There’s so much to think about and so many moving pieces that need to be managed that I wouldn’t blame you for resorting to a form library or even some type of form widget that handles it all for you.
But doing it by hand can be a good exercise and a great way to polish the basics. I’ll show you how I built my first multi-step form, and I hope you’ll not only see how approachable it can be but maybe even spot areas to make my work even better.
We’ll walk through the structure together. We’ll build a job application, which I think many of us can relate to these recent days. I’ll scaffold the baseline HTML, CSS, and JavaScript first, and then we’ll look at considerations for accessibility and validation.
I’ve created a GitHub repo for the final code if you want to refer to it along the way.
The structure of a multi-step form
Our job application form has four sections, the last of which is a summary view, where we show the user all their answers before they submit them. To achieve this, we divide the HTML into four sections, each identified with an ID, and add navigation at the bottom of the page. I’ll give you that baseline HTML in the next section.
Navigating the user to move through sections means we’ll also include a visual indicator for what step they are at and how many steps are left. This indicator can be a simple dynamic text that updates according to the active step or a fancier progress bar type of indicator. We’ll do the former to keep things simple and focused on the multi-step nature of the form.,
The structure and basic styles
We’ll focus more on the logic, but I will provide the code snippets and a link to the complete code at the end.
Let’s start by creating a folder to hold our pages. Then, create an index.html file and paste the following into it:
Open HTML
<form id="myForm"> <section class="group-one" id="one"> <div class="form-group"> <div class="form-control"> <label for="name">Name <span style="color: red;">*</span></label> <input type="text" id="name" name="name" placeholder="Enter your name"> </div> <div class="form-control"> <label for="idNum">ID number <span style="color: red;">*</span></label> <input type="number" id="idNum" name="idNum" placeholder="Enter your ID number"> </div> </div> <div class="form-group"> <div class="form-control"> <label for="email">Email <span style="color: red;">*</span></label> <input type="email" id="email" name="email" placeholder="Enter your email"> </div> <div class="form-control"> <label for="birthdate">Date of Birth <span style="color: red;">*</span></label> <input type="date" id="birthdate" name="birthdate" max="2006-10-01" min="1924-01-01"> </div> </div> </section> <section class="group-two" id="two"> <div class="form-control"> <label for="document">Upload CV <span style="color: red;">*</span></label> <input type="file" name="document" id="document"> </div> <div class="form-control"> <label for="department">Department <span style="color: red;">*</span></label> <select id="department" name="department"> <option value="">Select a department</option> <option value="hr">Human Resources</option> <option value="it">Information Technology</option> <option value="finance">Finance</option> </select> </div> </section> <section class="group-three" id="three"> <div class="form-control"> <label for="skills">Skills (Optional)</label> <textarea id="skills" name="skills" rows="4" placeholder="Enter your skills"></textarea> </div> <div class="form-control"> <input type="checkbox" name="terms" id="terms"> <label for="terms">I agree to the terms and conditions <span style="color: red;">*</span></label> </div> <button id="btn" type="submit">Confirm and Submit</button> </section> <div class="arrows"> <button type="button" id="navLeft">Previous</button> <span id="stepInfo"></span> <button type="button" id="navRight">Next</button> </div> </form> <script src="script.js"></script>
Looking at the code, you can see three sections and the navigation group. The sections contain form inputs and no native form validation. This is to give us better control of displaying the error messages because native form validation is only triggered when you click the submit button.
Next, create a styles.css file and paste this into it:
Open base styles
:root --primary-color: #8c852a; --secondary-color: #858034; body font-family: sans-serif; line-height: 1.4; margin: 0 auto; padding: 20px; background-color: #f4f4f4; max-width: 600px; h1 text-align: center; form background: #fff; padding: 40px; border-radius: 5px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); display: flex; flex-direction: column; .form-group display: flex; gap: 7%; .form-group > div width: 100%; input:not([type="checkbox"]), select, textarea width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px; .form-control margin-bottom: 15px; button display: block; width: 100%; padding: 10px; color: white; background-color: var(--primary-color); border: none; border-radius: 4px; cursor: pointer; font-size: 16px; button:hover background-color: var(--secondary-color); .group-two, .group-three display: none; .arrows display: flex; justify-content: space-between align-items: center; margin-top: 10px; #navLeft, #navRight width: fit-content; @media screen and (max-width: 600px) .form-group flex-direction: column;
Open up the HTML file in the browser, and you should get something like the two-column layout in the following screenshot, complete with the current page indicator and navigation.
Adding functionality with vanilla JavaScript
Now, create a script.js file in the same directory as the HTML and CSS files and paste the following JavaScript into it:
Open base scripts
const stepInfo = document.getElementById("stepInfo"); const navLeft = document.getElementById("navLeft"); const navRight = document.getElementById("navRight"); const form = document.getElementById("myForm"); const formSteps = ["one", "two", "three"]; let currentStep = 0; function updateStepVisibility() formSteps.forEach((step) => document.getElementById(step).style.display = "none"; ); document.getElementById(formSteps[currentStep]).style.display = "block"; stepInfo.textContent = `Step $currentStep + 1 of $formSteps.length`; navLeft.style.display = currentStep === 0 ? "none" : "block"; navRight.style.display = currentStep === formSteps.length - 1 ? "none" : "block"; document.addEventListener("DOMContentLoaded", () => navLeft.style.display = "none"; updateStepVisibility(); navRight.addEventListener("click", () => if (currentStep < formSteps.length - 1) currentStep++; updateStepVisibility(); ); navLeft.addEventListener("click", () => if (currentStep > 0) currentStep--; updateStepVisibility(); ); );
This script defines a method that shows and hides the section depending on the formStep values that correspond to the IDs of the form sections. It updates stepInfo with the current active section of the form. This dynamic text acts as a progress indicator to the user.
It then adds logic that waits for the page to load and click events to the navigation buttons to enable cycling through the different form sections. If you refresh your page, you will see that the multi-step form works as expected.
Multi-step form navigation
Let’s dive deeper into what the Javascript code above is doing. In the updateStepVisibility() function, we first hide all the sections to have a clean slate:
formSteps.forEach((step) => document.getElementById(step).style.display = "none"; );
Then, we show the currently active section:
document.getElementById(formSteps[currentStep]).style.display = "block";`
Next, we update the text that indicators progress through the form:
stepInfo.textContent = `Step $currentStep + 1 of $formSteps.length`;
Finally, we hide the Previous button if we are at the first step and hide the Next button if we are at the last section:
navLeft.style.display = currentStep === 0 ? "none" : "block"; navRight.style.display = currentStep === formSteps.length - 1 ? "none" : "block";
Let’s look at what happens when the page loads. We first hide the Previous button as the form loads on the first section:
document.addEventListener("DOMContentLoaded", () => navLeft.style.display = "none"; updateStepVisibility();
Then we grab the Next button and add a click event that conditionally increments the current step count and then calls the updateStepVisibility() function, which then updates the new section to be displayed:
navRight.addEventListener("click", () => if (currentStep < formSteps.length - 1) currentStep++; updateStepVisibility(); );
Finally, we grab the Previous button and do the same thing but in reverse. Here, we are conditionally decrementing the step count and calling the updateStepVisibility():
navLeft.addEventListener("click", () => if (currentStep > 0) currentStep--; updateStepVisibility(); );
Handling errors
Have you ever spent a good 10+ minutes filling out a form only to submit it and get vague errors telling you to correct this and that? I prefer it when a form tells me right away that something’s amiss so that I can correct it before I ever get to the Submit button. That’s what we’ll do in our form.
Our principle is to clearly indicate which controls have errors and give meaningful error messages. Clear errors as the user takes necessary actions. Let’s add some validation to our form. First, let’s grab the necessary input elements and add this to the existing ones:
const nameInput = document.getElementById("name"); const idNumInput = document.getElementById("idNum"); const emailInput = document.getElementById("email"); const birthdateInput = document.getElementById("birthdate") const documentInput = document.getElementById("document"); const departmentInput = document.getElementById("department"); const termsCheckbox = document.getElementById("terms"); const skillsInput = document.getElementById("skills");
Then, add a function to validate the steps:
Open validation script
function validateStep(step)
Here, we check if each required input has some value and if the email input has a valid input. Then, we set the isValid boolean accordingly. We also call a showError() function, which we haven’t defined yet.
Paste this code above the validateStep() function:
function showError(input, message) const formControl = input.parentElement; const errorSpan = formControl.querySelector(".error-message"); input.classList.add("error"); errorSpan.textContent = message;
Now, add the following styles to the stylesheet:
Open validation styles
input:focus, select:focus, textarea:focus outline: .5px solid var(--primary-color); input.error, select.error, textarea.error outline: .5px solid red; .error-message font-size: x-small; color: red; display: block; margin-top: 2px; .arrows color: var(--primary-color); font-size: 18px; font-weight: 900; #navLeft, #navRight display: flex; align-items: center; gap: 10px; #stepInfo color: var(--primary-color);
If you refresh the form, you will see that the buttons do not take you to the next section till the inputs are considered valid:
Finally, we want to add real-time error handling so that the errors go away when the user starts inputting the correct information. Add this function below the validateStep() function:
Open real-time validation script
function setupRealtimeValidation() nameInput.addEventListener("input", () => if (nameInput.value.trim() !== "") clearError(nameInput); ); idNumInput.addEventListener("input", () => if (idNumInput.value.trim() !== "") clearError(idNumInput); ); emailInput.addEventListener("input", () => if (emailInput.validity.valid) clearError(emailInput); ); birthdateInput.addEventListener("change", () => if (birthdateInput.value !== "") clearError(birthdateInput); ); documentInput.addEventListener("change", () => if (documentInput.files[0]) clearError(documentInput); ); departmentInput.addEventListener("change", () => if (departmentInput.value !== "") clearError(departmentInput); ); termsCheckbox.addEventListener("change", () => if (termsCheckbox.checked) clearError(termsCheckbox); );
This function clears the errors if the input is no longer invalid by listening to input and change events then calling a function to clear the errors. Paste the clearError() function below the showError() one:
function clearError(input) const formControl = input.parentElement; const errorSpan = formControl.querySelector(".error-message"); input.classList.remove("error"); errorSpan.textContent = "";
And now the errors clear when the user types in the correct value:
The multi-step form now handles errors gracefully. If you do decide to keep the errors till the end of the form, then at the very least, jump the user back to the erroring form control and show some indication of how many errors they need to fix.
Handling form submission
In a multi-step form, it is valuable to show the user a summary of all their answers at the end before they submit and to offer them an option to edit their answers if necessary. The person can’t see the previous steps without navigating backward, so showing a summary at the last step gives assurance and a chance to correct any mistakes.
Let’s add a fourth section to the markup to hold this summary view and move the submit button within it. Paste this just below the third section in index.html:
Open HTML
<section class="group-four" id="four"> <div class="summary-section"> <p>Name: </p> <p id="name-val"></p> <button type="button" class="edit-btn" id="name-edit"> <span>✎</span> <span>Edit</span> </button> </div> <div class="summary-section"> <p>ID Number: </p> <p id="id-val"></p> <button type="button" class="edit-btn" id="id-edit"> <span>✎</span> <span>Edit</span> </button> </div> <div class="summary-section"> <p>Email: </p> <p id="email-val"></p> <button type="button" class="edit-btn" id="email-edit"> <span>✎</span> <span>Edit</span> </button> </div> <div class="summary-section"> <p>Date of Birth: </p> <p id="bd-val"></p> <button type="button" class="edit-btn" id="bd-edit"> <span>✎</span> <span>Edit</span> </button> </div> <div class="summary-section"> <p>CV/Resume: </p> <p id="cv-val"></p> <button type="button" class="edit-btn" id="cv-edit"> <span>✎</span> <span>Edit</span> </button> </div> <div class="summary-section"> <p>Department: </p> <p id="dept-val"></p> <button type="button" class="edit-btn" id="dept-edit"> <span>✎</span> <span>Edit</span> </button> </div> <div class="summary-section"> <p>Skills: </p> <p id="skills-val"></p> <button type="button" class="edit-btn" id="skills-edit"> <span>✎</span> <span>Edit</span> </button> </div> <button id="btn" type="submit">Confirm and Submit</button> </section>
Then update the formStep in your Javascript to read:
const formSteps = ["one", "two", "three", "four"];
Finally, add the following classes to styles.css:
.summary-section display: flex; align-items: center; gap: 10px; .summary-section p:first-child width: 30%; flex-shrink: 0; border-right: 1px solid var(--secondary-color); .summary-section p:nth-child(2) width: 45%; flex-shrink: 0; padding-left: 10px; .edit-btn width: 25%; margin-left: auto; background-color: transparent; color: var(--primary-color); border: .7px solid var(--primary-color); border-radius: 5px; padding: 5px; .edit-btn:hover border: 2px solid var(--primary-color); font-weight: bolder; background-color: transparent;
Now, add the following to the top of the script.js file where the other consts are:
const nameVal = document.getElementById("name-val"); const idVal = document.getElementById("id-val"); const emailVal = document.getElementById("email-val"); const bdVal = document.getElementById("bd-val") const cvVal = document.getElementById("cv-val"); const deptVal = document.getElementById("dept-val"); const skillsVal = document.getElementById("skills-val"); const editButtons = "name-edit": 0, "id-edit": 0, "email-edit": 0, "bd-edit": 0, "cv-edit": 1, "dept-edit": 1, "skills-edit": 2 ;
Then add this function in scripts.js:
function updateSummaryValues() nameVal.textContent = nameInput.value; idVal.textContent = idNumInput.value; emailVal.textContent = emailInput.value; bdVal.textContent = birthdateInput.value; const fileName = documentInput.files[0]?.name; if (fileName) const extension = fileName.split(".").pop(); const baseName = fileName.split(".")[0]; const truncatedName = baseName.length > 10 ? baseName.substring(0, 10) + "..." : baseName; cvVal.textContent = `$truncatedName.$extension`; else cvVal.textContent = "No file selected"; deptVal.textContent = departmentInput.value; skillsVal.textContent = skillsInput.value || "No skills submitted"; }
This dynamically inserts the input values into the summary section of the form, truncates the file names, and offers a fallback text for the input that was not required.
Then update the updateStepVisibility() function to call the new function:
function updateStepVisibility() formSteps.forEach((step) => document.getElementById(step).style.display = "none"; ); document.getElementById(formSteps[currentStep]).style.display = "block"; stepInfo.textContent = `Step $currentStep + 1 of $formSteps.length`; if (currentStep === 3) updateSummaryValues(); navLeft.style.display = currentStep === 0 ? "none" : "block"; navRight.style.display = currentStep === formSteps.length - 1 ? "none" : "block";
Finally, add this to the DOMContentLoaded event listener:
Object.keys(editButtons).forEach((buttonId) => const button = document.getElementById(buttonId); button.addEventListener("click", (e) => currentStep = editButtons[buttonId]; updateStepVisibility(); ); );
Running the form, you should see that the summary section shows all the inputted values and allows the user to edit any before submitting the information:
And now, we can submit our form:
form.addEventListener("submit", (e) => e.preventDefault(); if (validateStep(2)) alert("Form submitted successfully!"); form.reset(); currentFormStep = 0; updateStepVisibility(); );
Our multi-step form now allows the user to edit and see all the information they provide before submitting it.
Accessibility tips
Making multi-step forms accessible starts with the basics: using semantic HTML. This is half the battle. It is closely followed by using appropriate form labels.
Other ways to make forms more accessible include giving enough room to elements that must be clicked on small screens and giving meaningful descriptions to the form navigation and progress indicators.
Offering feedback to the user is an important part of it; it’s not great to auto-dismiss user feedback after a certain amount of time but to allow the user to dismiss it themselves. Paying attention to contrast and font choice is important, too, as they both affect how readable your form is.
Let’s make the following adjustments to the markup for more technical accessibility:
Add aria-required="true" to all inputs except the skills one. This lets screen readers know the fields are required without relying on native validation.
Add role="alert" to the error spans. This helps screen readers know to give it importance when the input is in an error state.
Add role="status" aria-live="polite" to the .stepInfo. This will help screen readers understand that the step info keeps tabs on a state, and the aria-live being set to polite indicates that should the value change, it does not need to immediately announce it.
In the script file, replace the showError() and clearError() functions with the following:
function showError(input, message) const formControl = input.parentElement; const errorSpan = formControl.querySelector(".error-message"); input.classList.add("error"); input.setAttribute("aria-invalid", "true"); input.setAttribute("aria-describedby", errorSpan.id); errorSpan.textContent = message; function clearError(input) const formControl = input.parentElement; const errorSpan = formControl.querySelector(".error-message"); input.classList.remove("error"); input.removeAttribute("aria-invalid"); input.removeAttribute("aria-describedby"); errorSpan.textContent = "";
Here, we programmatically add and remove attributes that explicitly tie the input with its error span and show that it is in an invalid state.
Finally, let’s add focus on the first input of every section; add the following code to the end of the updateStepVisibility() function:
const currentStepElement = document.getElementById(formSteps[currentStep]); const firstInput = currentStepElement.querySelector( "input, select, textarea" ); if (firstInput) firstInput.focus();
And with that, the multi-step form is much more accessible.
Conclusion
There we go, a four-part multi-step form for a job application! As I said at the top of this article, there’s a lot to juggle — so much so that I wouldn’t fault you for looking for an out-of-the-box solution.
But if you have to hand-roll a multi-step form, hopefully now you see it’s not a death sentence. There’s a happy path that gets you there, complete with navigation and validation, without turning away from good, accessible practices.
And this is just how I approached it! Again, I took this on as a personal challenge to see how far I could get, and I’m pretty happy with it. But I’d love to know if you see additional opportunities to make this even more mindful of the user experience and considerate of accessibility.
References
Here are some relevant links I referred to when writing this article:
How to Structure a Web Form (MDN)
Multi-page Forms (W3C.org)
Create accessible forms (A11y Project)
#:not#Accessibility#ADD#aria#Article#Articles#attention#attributes#background#border-radius#box#box-shadow#browser#buttons#challenge#change#classes#code#Color#content#CSS#CV#dept#direction#display#email#error handling#event#Events#Exercise
3 notes
·
View notes
Text
as many varieties of experiencing the divine as there are and that i can appreciate one of them that as trans person makes me stumble is the divine feminine/masculine dichotomy. there are so many conceptions of divinity like the trinity and pantheons and monotheism and saints and spirits and i try to appreciate them all. but to deify gender essentialist ideas, put everything into masculine or femininity categories, imply that feminism should be about fulfilling strict but "natural" gender roles, purity culture, traditionalism and essentialism is wild to me. the people who love this also hate trans people. im not surprised considering everything else (the tradwife tradcath and divine feminine worshipper venn diagram) but god is it mind boggling
#i think the whole divine feminine is a gateway to the trad wife movement honestly#if you love gender that much you would think they appreciate the everyday lives of trans people considering how we play with it#but apparently we are blasphemy to them in some way? its interesting#it reminds me too much of compartmentalism. my theology is one that wants to be liberatory and expansive not whatever is going on over ther#also why melt down every deity just to their gender and mix them together? they have other attributes besides being feminine or masculine#what gets me is that you wanna understand the vastness of divinity. so we're gonna use a 2 category system and smash everything in there?#people invented that! its fake! its faker than most things!#im a divinefeminine/divinemasculine hater at heart#religion#spirituality#trans spirituality#trans theology#cant find it in me to love every religious concept sorry i prayed for tranquility and now im content with being a hater and a lover
5 notes
·
View notes
Text
last day before cobra kai trailer drops, manifesting kyler & shawn interacting 🤞
#also now thinking about it#new ck s6 content dropping after pride month ends lol#ik that's more attributable to coincidence but also that's funny to think about lol#cobra kai#cobra kai season 6
3 notes
·
View notes
Text

demand
#peremptory physiques that display in advance the future contents of their parts#you don't know my attributes
4 notes
·
View notes
Note
Sorry to bother you with this but I was actually wondering how you got into funger...? 😅 I've seen a video that breaks down how the game works mechanically, but I'm interested in learning the whole story side of things. Have you played the game yourself? Watched a video? What would you recommend?
OMG i actually got into it thru a speedrun vid that was randomly recommended to me on yt 😭😭 then i looked it up and thus began the funger rabbit hole …
for the lore side i ended up watching worm girls vids on both funger & funger termina on loop during my commutes !!
youtube
youtube
both vids r super in depth and collate the diff routes into easy-to-follow & linear narratives !! plus a bit of reading thru doesthedogdie & tvtropes pages (my usual go-tos when getting into any new media tbh) aaand some no commentary playthroughs & other clip comps for more context :> (aaand a bit of funger reddit + wiki)
i havent played thru it myself bec my video game budget is down the drain + already watching any sort of gameplay vid gives me a headache so im mostly stuck on watching other ppl play. so most of my secondhand gameplay experience comes from when i rec’d it to a friend who loves games w brutal mechanics and they streamed it with me !! aside from that, i mostly watch speedrun vids, plus vods + clips from tolo and mauthedoog !!
additionally.. the shitposts also rly helped clue me in on the funger experience ... super helpful getting into the gameplay + lore jokes even w/out having played .. im a big fan of everlasting soul's stuff + anything similar to the funger bechdel test !!! which makes me keel over every time
#i talk#asks#funger#and this doesnt even cover whatever else the fanart has which all also rule ...#so ya!! this is how i still contracted brainrot w/out having played it myself heeheee...#i also havent touched cdawg's vid on it actually but i think the funger resurgence can be attributed to that as well....? not sure#im not on tiktok but knowyourmeme attributes its 2023 popularity to. the tiktok content too but i dont have anything on that lololol#so ya !! yippee!!! thank u for letting me ramble abt my funger experience
2 notes
·
View notes