I want to dynamically add a <br> element after a dynamically added <div>. Even though the <br> is added in the code (I saw it under Elements in Chrome), the line doesnt appear on the screen. This is my code:
let guests = document.createDocumentFragment();
let k = 0;
let name = [];
for(let j = 0; j < compositions[i].guests.length; j++){
var br = document.createElement("br");
let divElement = document.createElement("div");
if(compositions[i].guests[k] != ";"){
name.push(compositions[i].guests[k]);
k++;
}
else {
k = k + 2;
divElement.innerHTML = name.join('');
divElement.setAttribute("class", "guestsDiv");
divElement.setAttribute("id", "guestsDiv");
divElement.setAttribute("style", "color:" + compositions[i].textColor);
guests.appendChild(br);
guests.appendChild(divElement);
//$('#guests').append('New Line<br>');
name = [];
}
}
This is the css:
.guestsDiv{
position: absolute;
display: none;
top: 16.5vw;
left: 59.5vw;
max-width: 2px;
font-size: 2vw;
line-height: 98%;
word-wrap: normal;
font-family: 'Quicksand', sans-serif;
}
The HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="css/config.css">
<link href="https://fonts.googleapis.com/css?family=Quicksand" rel="stylesheet">
<script src="js/jquery-3.3.1.min.js"></script>
<script src="js/config.js" defer></script>
<script src="js/main.js" defer></script>
</head>
<body>
<input type="text" class="config" id="backgroundImage" name="lname" placeholder="Background Image">
<br>
<input type="text" class="config" id="animation" name="lname" placeholder="Animation">
<br>
<input type="text" class="config" id="textColor" name="lname" placeholder="Text Color">
<br>
<input type="text" class="config" id="overlay" name="lname" placeholder="Overlay">
<br>
<input type="text" class="config" id="startDate" name="lname" placeholder="Start Date">
<br>
<input type="text" class="config" id="endDate" name="lname" placeholder="End Date">
<br>
<input id="clickMe" type="button" value="Enter values" onclick="configComp();"/>
<img id="setBackground">
<img id="logo">
<div id="rectangle"></div>
<div id="smallRectangle"></div>
<div id="welcomeFirstLine" style="position:absolute"></div>
<div id="welcomeSecondLine" style="position:absolute"></div>
<div id="emptyText" style="position:absolute"></div>
</body>
<script src='https://cdnjs.cloudflare.com/ajax/libs/velocity/1.5.0/velocity.min.js'></script>
<script src='https://s3-us-west-2.amazonaws.com/s.cdpn.io/2/velocity.ui.min.js'></script>
</html>
It has to be something easy, but I cant see what. What am I doing wrong? Thanks!
P.S.: If you also have some other suggestions about my code I'm open to it. So please feel free to give me any feedback.
Edit: For clarification: all elements are shown, but one on top of eachother and not one under eachother as I want.
Edit2: More code added.
I guess it's an issue with the creation of br element. The thing is you are using the same br element each time in the loop, which means each time the dom paints it at different positions throughout the loop (which here is before the new div).
So you can either clone the br element or create a new one each time like :
let guests = document.createDocumentFragment();
let k = 0;
let name = [];
var br = document.createElement("br"); //<-- Outside, to avoid redeclaration.
for(let j = 0; j < compositions[i].guests.length; j++){
let divElement = document.createElement("div");
if(compositions[i].guests[k] != ";"){
name.push(compositions[i].guests[k]);
k++;
}
else {
k = k + 2;
divElement.innerHTML = name.join('');
divElement.setAttribute("class", "guestsDiv");
divElement.setAttribute("id", "guestsDiv");
divElement.setAttribute("style", "color:" + compositions[i].textColor);
guests.appendChild(br.cloneNode()); // <-- Here cloneNode() creates a new clone of br each time.
guests.appendChild(divElement);
//$('#guests').append('New Line<br>');
name = [];
}
}
Related
I am trying to create a loop. so far I can get it to say Hello Tom and just the number. I want to add on a function named addOrderListItems that receives the name and numOfTimes as parameters. Then call the addOrderListItems function from the displayHello function and if the number is even add an !
so if I type name Braden and numOfTimes 8
the output will display a list
1.Hello Braden
2.Hello Braden!
3.Hello Braden
4.Hello Braden!
5.Hello Braden
6.Hello Braden!
7.Hello Braden
8.Hello Braden!
9.Hello Braden
function displayHello() {
let name = document.getElementById("helloNameInput").value,
numOfTimes = document.getElementById("numOfTimesInput").value;
}
function addOrderListItems() {
let numOfTimes = 0;
while (numOfTimes > 0 ) {
document.getElementById("helloNameOutput").innerHTML = "Hello " + name + numOfTimes;
numOfTimes++;
}
}
function clearName() {
document.getElementById("helloNameInput").value = "";
document.getElementById("numOfTimesInput").value = "";
document.getElementById("helloNameOutput").innerText = "";
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>JavaScript: Looping Structures Assignment</title>
<link href="/bootstrap.min.css" rel="stylesheet" />
</head>
<body class="p-3">
<h1>JavaScript: Looping Structures Assignment</h1>
<!--Name input-->
<div class="mb-3">
<label for="helloNameInput" class="form-label">Name:</label>
<input
type="text"
class="form-control"
name="helloNameInput"
id="helloNameInput"
placeholder="Enter a name"
/>
</div>
<!--Number of Times input-->
<div class="mb-3">
<label for="numOfTimesInput" class="form-label">Number of Times:</label>
<input
type="text"
class="form-control"
name="numOfTimesInput"
id="numOfTimesInput"
placeholder="Enter number"
/>
</div>
<!--Name output-->
<ol id="helloNameOutput"></ol>
<!--Display Hello! & Reset buttons-->
<div>
<button class="btn btn-primary" id="displayHelloButton" onclick="displayHello();" >
Display Hello!
</button>
<button class="btn btn-danger" id="clearButton" onclick=" clearName();">Clear</button>
</div>
<script src="/script.js"></script>
</body>
</html>
```
You'll probably need a few functions to help you accomplish your goal and keep your code organized. Below I've created an example in a code snippet to demonstrate how the functionality you described can be implemented. I've included lots of comments to explain and help you understand the steps involved.
You can search on MDN and read the JavaScript documentation if there are parts you've never seen or don't yet understand — for example, here are a few links to some of the DOM APIs used:
Document.createElement()
Element.remove()
Node.firstChild
Node.appendChild()
Keep learning, and good luck in your programming!
const nameInput = document.getElementById('helloNameInput');
const qtyInput = document.getElementById('numOfTimesInput');
const btn = document.getElementById('writeGreeting');
const output = document.getElementById('helloNameOutput');
function createGreetingText (name, withExclamationPoint) {
return `Hello ${name}${withExclamationPoint ? '!' : ''}`;
}
function createGreetingListItem (name, withExclamationPoint) {
const listItem = document.createElement('li');
listItem.textContent = createGreetingText(name, withExclamationPoint);
return listItem;
}
function clearOutput () {
// Delete every child element from the output element:
while (output.firstChild) {
output.firstChild.remove();
}
}
function writeGreeting () {
// Get the trimmed input value (or use "world" if it's empty):
const name = nameInput.value.trim() || 'world';
// Get the number of times (quantity) from the other input:
let qty = parseInt(qtyInput.value);
// If the number input value couldn't be parsed as a valid integer,
// use 1 as the default valid value and update the input:
if (!Number.isInteger(qty)) {
qty = 1;
qtyInput.value = 1;
}
clearOutput();
// Loop the number of times:
for (let i = 1; i <= qty; i += 1) {
// Create and append a list item element each time:
const isEven = i % 2 === 0;
const listItem = createGreetingListItem(name, isEven);
output.appendChild(listItem);
}
}
// Bind the "writeGreeting" function to the button's "click" event,
// so that it runs each time the button is clicked:
btn.addEventListener('click', writeGreeting);
#container {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 1rem;
font-family: sans-serif;
}
button, input {
font-size: 1rem;
padding: 0.5rem;
}
<div id="container">
<input
type="text"
id="helloNameInput"
placeholder="name"
value="Braden"
/>
<input
type="number"
step="1"
min="1"
id="numOfTimesInput"
placeholder="# of times"
value="8"
/>
<button id="writeGreeting">Write greeting</button>
<ol id="helloNameOutput"></ol>
</div>
I have an HTML Form that a user needs to fill out. It is information about a Student (Name, Email, Grade, Math, English, Social Studies). What I am trying to do is when the user fills out the Form and clicks the Submit button. It creates a JavaScript Object and adds it into another JS Object. I want the information input in the Form to display at the bottom of the webpage. I am purposely not using a database. I just want the information to exist while the page is up.
This is the HTML Form:
<!DOCTYPE html>
<html lang="en">
<head>
<!--Required Meta Tag-->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
<style>
.center {
text-align: center;
border: 3px solid green;
}
body {
font-family: Arial;
margin: 0;
}
/* Header/Logo Title */
.header {
padding: 10px;
text-align: center;
background: #1abc9c;
color: white;
font-size: 20px;
}
</style>
<title>Student Report Card</title>
</head>
<body>
<div class="header">
<br>
<h2>Student & Grade Input Form</h2>
<br>
</div>
<br>
<div class="container">
<h1>Register</h1>
<p>Please fill in this form to create an account.</p>
<input type="text" placeholder="Enter name" name="name" id="name" required><br>
<br>
<input type="email" placeholder="Enter Email" name="email" id="email" required><br>
<br>
<input type="number" placeholder="Enter Math Grade" name="math" id="math" required><br>
<br>
<input type="number" placeholder="Enter English Grade" name="eng" id="eng" required><br>
<br>
<input type="number" placeholder="Enter Math Grade" name="math" id="math" required><br>
<br>
<input type="number" placeholder="Enter Social Studies Grade" name="sstd" id="sstd" required><br>
<br>
<button type="submit" id="btn1">Submit</button>
<ul id="myList">
</ul>
</div>
<script src="scripts.js"></script>
</body>
</html>
This is the Javascript Code:
document.getElementById("btn1").addEventListener("click", inputFunc)
var studentList = new Object()
function inputFunc(){
var fname = document.getElementById("name").value
var email = document.getElementById("email").value
var math = document.getElementById("math").value
var eng = document.getElementById("eng").value
var sstd = document.getElementById("sstd").value
var x = Math.floor((Math.random() * 100) + 1);
var y = x.toString();
studentID = "student".concat(y)
var studentID = new Object();
studentID.name = fname
studentID.email = email
studentID.math = math
studentID.eng = eng
studentID.sstd = sstd
studentList[studentID] = studentID
console.log(studentList)
var obj = JSON.parse(JSON.stringify(studentList))
var information = document.getElementById("demo").innerHTML = obj.fname + ", " + obj.email + ", " + obj.math;
var node = document.createElement("LI");
var textnode = document.createTextNode(information);
node.appendChild(textnode);
document.getElementById("myList").appendChild(node);
}
I am using the Random() method in JavaScript to create a random number that I am concatenating to the the "student" so it give it a unique ID. This is working correctly. I just can't display the information at the bottom of the page.
The Goal is after the user inputs information in the form it will display the content of the object below like so:
- Name, Email, Grade, English, Math, Social Studies
- Name, Email, Grade, English, Math, Social Studies
- Name, Email, Grade, English, Math, Social Studies
I have been able to solve this. I was able to create an html table and dynamically fill it as a user inputs information. The javascript will add the information dynamically to the first row and continue to do so as more information is added.
Updated HTML below:
<!DOCTYPE html>
<html lang="en">
<head>
<!--Required Meta Tag-->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
<style>
.center {
text-align: center;
border: 3px solid green;
}
body {
font-family: Arial;
margin: 0;
}
/* Header/Logo Title */
.header {
padding: 10px;
text-align: center;
background: #1abc9c;
color: white;
font-size: 20px;
}
table, td {
border: 1px solid black;
padding: 8px;
}
</style>
<title>Student Report Card</title>
</head>
<body>
<div class="header">
<br>
<h2>Student & Grade Input Form</h2>
<br>
</div>
<br>
<div class="container">
<h1>Register</h1>
<p>Please fill in this form to create an account.</p>
<input type="text" placeholder="Enter name" name="name" id="name" required><br>
<br>
<input type="email" placeholder="Enter Email" name="email" id="email" required><br>
<br>
<input type="number" placeholder="Enter Math Grade" name="math" id="math" required><br>
<br>
<input type="number" placeholder="Enter English Grade" name="eng" id="eng" required><br>
<br>
<input type="number" placeholder="Enter Social Studies Grade" name="sstd" id="sstd" required><br>
<br>
<button type="submit" id="btn1">Submit</button>
<br><br>
<table id="myTable">
<tr>
<td>Name</td>
<td>Email</td>
<td>Math Grade</td>
<td>English Grade</td>
<td>Social Studies Grade</td>
</tr>
</table>
</div>
<script src="scripts.js"></script>
</body>
</html>
Updated Javascript below:
var studentList = new Object()
function inputFunc(){
var fname = document.getElementById("name").value
var email = document.getElementById("email").value
var math = document.getElementById("math").value
var eng = document.getElementById("eng").value
var sstd = document.getElementById("sstd").value
var x = Math.floor((Math.random() * 100) + 1);
var y = x.toString();
studentID = "student".concat(y)
studentNumber = "student".concat(y)
var studentID = new Object();
studentID.name = fname
studentID.email = email
studentID.math = math
studentID.eng = eng
studentID.sstd = sstd
studentList[studentNumber] = studentID
// variable of javascript object, place each element in a variable with stringfy
var studentInformation = studentList[studentNumber]
console.log(typeof studentInformation)
var obj = String(studentInformation.name)
var obj1 = String(studentInformation.email)
var obj2 = String(studentInformation.math)
var obj3 = String(studentInformation.eng)
var obj4 = String(studentInformation.sstd)
var table = document.getElementById("myTable");
var row = table.insertRow(1);
var cell1 = row.insertCell(0)
var cell2 = row.insertCell(1);
var cell3 = row.insertCell(2);
var cell4 = row.insertCell(3);
var cell5 = row.insertCell(4);
cell1.innerHTML = obj;
cell2.innerHTML = obj1;
cell3.innerHTML = obj2;
cell4.innerHTML = obj3;
cell5.innerHTML = obj4;
}
I think this is just an issue of adding items to objects. Here is an example
let studentInfo;
studentInfo.push({ name: "John", email: "john#gmail.com" });
This answer in incorrect.
I'm rather new to javascript and i'm trying to make a calculator that instantly calculates a total price of selected products.
The calculator works fine but right now the checkbox gets calculated alongside the rest of the products even when unchecked.
I'm trying to make it so that when it is unchecked the value is 0 and when it is checked it is 0.50.
This is what I have so far:
<head>
<style type="text/css">
.right{
margin-top: 10px;
width: 150px;
height: 45px;
background-color: #66CCFF;
}
p{
margin: 0;
padding: 0;
}
</style>
<script type="text/javascript">
<!--
function calculate() {
var A1 = document.getElementById('Amount1').value
var A2 = document.getElementById('Amount2').value
var A3 = document.getElementById('Amount3').value
var PStart = 0;
var P1 = A1*1.50;
var P2 = A2*1.00;
var P3 = A3*1.00;
var PTotal = P1+P2+P3;
var Insert = document.getElementById("TotalPrice");
TotalPrice.innerHTML= PTotal;
}
-->
</script>
</head>
<body onload="calculate()">
<form>
<fieldset>
<legend>Price</legend>
<div class="FormRow">
<label for="Amount2">Console $1,50</label>
<input type="text" min=0 id="Amount1" name="Amount1" oninput="calculate()" />
</div>
<div class="FormRow">
<label for="Amount2">Controller $1,00</label>
<input type="text" min=0 id="Amount2" name="Amount2" oninput="calculate()" />
</div>
<div class="FormRow">
<label for="Amount3">Batteries? $0,50</label>
<input type="checkbox" value="0.50" id="Amount3" name="Amount3" onchange="calculate()"/>
</div>
<div class="right" >
<p><b>Total price:</b></p>
<p id="TotalPrice">
</p>
</div>
</fieldset>
</form>
</body>
Try this:
var A1 = document.getElementById('Amount1').value
var A2 = document.getElementById('Amount2').value
var A3 = document.getElementById('Amount3').checked ?
document.getElementById('Amount3').value : 0;
Demo
You can use document.getElementById('Amount1').checked to verify if the checkbox is checked. So your code would look like
var A1 = document.getElementById('Amount1').checked ?
parseFloat(document.getElementById('Amount1').value) :
0;
var A2 = document.getElementById('Amount1').checked ?
parseFloat(document.getElementById('Amount1').value) :
0;
var Total = A1 + A2;
I create a div and its css id like this.
<div id="r1" class="ansbox"></div>
<div id="r2" class="ansbox"></div>
<div id="r3" class="ansbox"></div>
<div id="r4" class="ansbox"></div>
<div id="r5" class="ansbox"></div>
<div id="r6" class="ansbox"></div>
<div id="r7" class="ansbox"></div>
<div id="r8" class="ansbox"></div>
<div id="r9" class="ansbox"></div>
<div id="r10" class="ansbox"></div>
is there a way to create this div using looping statement. Anyone help me..
I would recommend using some javascript (without jquery) for performance:
var toAdd = document.createDocumentFragment();
for(var i=0; i < 11; i++){
var newDiv = document.createElement('div');
newDiv.id = 'r'+i;
newDiv.className = 'ansbox';
toAdd.appendChild(newDiv);
}
document.appendChild(toAdd);
This way you only make one append(), only 1 reflow, and you don't need jQuery.
To append it to a jQuery selector:
$('sel').append(toAdd);
Or a dom element:
document.getElementById('sel').appendChild(toAdd);
Suppose you have following div where you will insert new divs:
<div id="target">
<!-- all divs will append here -->
</div>
jQuery:
for(var i =1; i<= 10; i++){
$('#target').append($('<div/>', { id: 'r' + i, 'class' : 'ansbox'}))
}
or
for(var i =1; i<= 10; i++){
$('#target').append('<div id="r'+ i +'" class="ansbox"></div>')
}
I will go for first approach.
Related refs:
.append()
Here's one option:
for(var i = 0; i <=10; i++) {
$('<div id="r'+i+'" class="ansbox"></div>').appendTo("target");
}
<div class="ibox-content" id="location-div">
<div class="row">
<div class="col-sm-12">
<button id="addlocation" type="button" class="btn btn-w-m btn-primary pull-right">Add new location</button>
</div>
</div>
<div class="row" style="margin-top:10px;">
<div class="col-sm-2">
<label class="form-label">Location <span ><input type="text" readonly id="locval" style="width:20px;border:0px;" value="1"></span></label>
</div>
<div class="col-sm-10">
<input type="text" name="" class="form-control ">
</div>
</div>
</div>
Here I want to add a dynamic row by adding 1 to each new entry this will solve your problem
<script>
$(document).ready(function(){
var inno = document.getElementById("locval").value;
for(var start = 1; inno >= start; start+=1)
{
start;
}
$("#addlocation").click(function(){
$("#location-div").append('<div class="row" style="margin-top:10px;"><div class="col-sm-2"><label class="form-label">Location <span ><input type="text" readonly id="locval" style="width:20px;border:0px" value="'+start+++'"></span> </label></div><div class="col-sm-10"><input type="text" name="" class="form-control "></div></div>');
});
});
</script>
I would recommend using simple javascript loop (without jquery) for performance:
let container = document.getElementById('container');
for (let i = 0; i <= 10; i++) {
let element = document.createElement('div');
container.appendChild(element);
};
console.log(container);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Answer</title>
</head>
<body>
<div id="container"></div>
</body>
</html>
let container = document.getElementById('container');
for (let i = 0; i <= 10; i++) {
let element = document.createElement('div');
container.appendChild(element);
};
Can anyone see where I could be making a mistake? The form text-box background colors are originally set to grey. If the user makes a mistake I want to turn them yellow with a red border. The function is sort of working, because the form is not going to the server when the form is filled out incorrectly. But the css doesn't change. If I comment out my js call it will post to the server. Here are the snippets:
CSS:
.invalid{
background-color:#ff9;
border: 2px red inset;
}
.reqd{
background-color:#222222;
color:#555555; border-style: solid;
border-color:#555555;
border-width: 1px;
}
HTML:
<!DOCTYPE html>
<?php
// Debug
error_reporting(E_ALL);
?>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="styles.css" type="text/css">
<script src="js/jquery-1.7.2.min.js"></script>
<script src="js/regauth.js"></script>
<title></title>
</head>
<body id="registerBody">
<section id="registerBox">
<form id="registerForm" method="post" action="regauth.php">
<p>Welcome to the atlas registraton! Please fill out the information below.</p>
<br>
<p><label for="firstName">First Name: <input type="text" size="30" id="firstName" name="firstName" class="reqd"></label></p>
<p><label for="lastName">Last Name: <input type="text" size="30" id="lastName" name="lastName" class="reqd"></label></p>
<p><label for="email">Email: <input type="text" size="30" id="email" name="email" class="reqd"></label></p>
<br>
<br>
<p><label for="reqUsername">Username: <input type="text" size="30" id="reqUsername" name="reqUsername" class="reqd"></label></p>
<p><label for="passOne">Password: <input type="password" size="30" id="passOne" name="passOne" class="reqd"></label></p>
<p><label for="passTwo">Confirm Password: <input type="password" size="30" id="passTwo" name="passTwo" class="reqd"></label></p>
<br>
<br>
<p><input type="submit" value="Submit"> <input type="reset" value="Reset Form" class="reset"></p>
</form>
</section>
<script type="text/javascript">
$("#registerBox").css("margin-left", ($(window).width()-425)/2);
$("#registerBox").css("margin-top", ($(document).height()-500)/2);
$('#registerBox').fadeIn(1500);
</script>
</body>
</html>
JS (regauth.js): Courtesy of Tom Negrino, Visual Quickstart Guide: Javascript Eighth Edition
window.onload = initForms;
//Function loops through each form. For each one it adds an event handler to that forms 'onSubmit'.
function initForms() {
for (var i = 0; i < document.forms.length; i++) {
document.forms[i].onsubmit = validForm;
}
}
function validForm() {
var allGood = true;
var allTags = document.getElementsByTagName("*");
for (var i = 0; i < allTags.length; i++) {
if (!validTag(allTags[i])) {
allGood = false;
}
}
return allGood;
function validTag(thisTag) {
var outClass = "";
var allClasses = thisTag.className.split(" ");
for (var j = 0; j < allClasses.length; j++) {
outClass += validBasedOnClass(allClasses[j]) + " ";
}
thisTag.className = outClass;
if (outClass.indexOf("invalid") > -1) {
thisTag.focus();
if (thisTag.nodeName == "INPUT") {
thisTag.select();
}
return false;
}
return true;
function validBasedOnClass(thisClass) {
var classBack = "";
switch (thisClass) {
case "":
case "invalid":
break;
case "reqd":
if (allGood && thisTag.value == "") {
classBack = "invalid ";
}
classBack += thisClass;
break;
default:
classBack += thisClass;
}
return classBack;
}
}
}
Move the "invalid" CSS block to after the "reqd" one.
The rules for CSS are that the "last rule wins" (sort-of; it's more complicated but in this case that's the issue).
Even though the "invalid" rules apply to the invalid elements, because the "reqd" rule has a background color and because it comes after the "invalid" rule, that setting applies.