Blog: Pros and Cons with Generative AI (More Posts)
Although part of me will always wonder if generative AI will ever come back at me and say “Do it yourself you lazy so and so”, I continue to be amazed and grateful for what AI can do for me.
A few days ago I had an idea for a new single page app. A DOM script that can build lists of pros and cons to help people make choices. I for one prefer to have things written in front of me rather than try to rely on my brain all the time. So I thought, why not try to build something to help me do that?
Here’s the markup that I built out to start with.
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- CSS -->
<link rel="stylesheet" type="text/css" href="style.css">
<!-- Page Title -->
<title>Weigh up the Pros and Cons</title>
</head>
<body>
<header>
<div><a href="log.php">v1</a></div>
<h1>Got a decision to make?</h1>
<h2>Weigh up the Pros and Cons</h2>
</header>
<main>
<section class="pro_con_card">
<article class="article---pro--con pro">
<h3>Pros</h3>
<ul class="list---container pro_container">
<li>list item 1</li>
<!-- <li>It's cheap</li>
<li>It's easy</li>
<li>It's fast</li>
<li>It's reliable</li>
<li>It's secure</li> -->
</ul>
<input type="text" value="" class="input_pro" id="js---input--pro-1" placeholder="Enter a Pro and press enter..." for="pro_item" title="" alt="" />
</article>
<article class="article---pro--con con">
<h3>Cons</h3>
<ul class="list---container con_container">
<!-- <li>It's expensive</li>
<li>It's complicated</li>
<li>It's difficult</li>
<li>It's unreliable</li>
<li>It's insecure</li> -->
</ul>
<input type="text" value="" class="input_pro" id="js---input--con-1" placeholder="Enter a Con and press enter..." for="con_item" title="" alt="" />
</article>
</section>
</main>
<aside>
<button class="btn btn---add--new" id="js---add_new">Add New Set</button>
</aside>
<footer>
<!-- TODO: Print out the Pros and Cons -->
<button class="btn btn---print" id="js---print_contents">Print</button>
</footer>
<script type="text/javascript" src="app.js"></script>
</body>
</html>
To summarise… this HTML page helps users list and compare pros and cons to aid their decision-making.
It includes: –
- A header element which contains A title, subtitle, and a link to a “log.php” file as child elements.
- A main element: This contains two columns of text—one for pros, one for cons—with input fields for users to add their own items.
- There’s an aside element which has a button to create a new pros/cons set.
- A footer element containing a “Print” button for printing the list as it is on the screen.
- Each column has a heading e,g, “Pros” followed by a list where the user can see pros or cons they’ve added (though initially, there’s only one example list item).
- The page also links to external CSS (`style.css`) for styling and includes JavaScript (`app.js`) which will make the application work.
The idea is to have dynamically generated columns where users can see pros and cons of a given decision side by side.
To kick off the nuts and bolts of the application, I gave the HTML and the following prompt to ChatGPT.
Each time a user adds text by pressing enter a new corresponding pro or con is added to the list.
I've made sure that the script file is linked and addeed some initial boilerplate styling.
You'll have seen buttons in this app to print the current lists on the screen and to add new sets to create more than one list
How much of this app can you do?
And how did it do? I rated it as an 8 out of 10 job. High marks because it got the functionality just fine with some cosmetic issues for us to talk about.
ChatGPT gave me a fully functional solution but I want to focus on 3 things in particular. It gave me a script that handled 3 main tasks.
1. Add Items to List on Enter – When the user types a “pro” or “con” using the associated input box and presses enter, we capture the input and append it to the corresponding list.
// Function to handle adding an item to the list when the Enter key is pressed
function addItem(inputField, listContainer) {
inputField.addEventListener('keydown', function (event) {
if (event.key === 'Enter' && inputField.value.trim() !== '') {
const newItem = document.createElement('li');
newItem.textContent = inputField.value;
listContainer.appendChild(newItem);
inputField.value = ''; // Clear input field
}
});
}
2. Add New Set – The “Add New Set” button allows the user to generate a new set of “Pros” and “Cons” input fields and lists dynamically.
// Attach listeners for existing Pros and Cons input fields
const proInput = document.getElementById('js---input--pro-1');
const proList = document.querySelector('.pro_container');
addItem(proInput, proList);
const conInput = document.getElementById('js---input--con-1');
const conList = document.querySelector('.con_container');
addItem(conInput, conList);
// Function to add a new Pros and Cons set
function addNewSet() {
const section = document.createElement('section');
section.classList.add('pro_con_card');
const proArticle = document.createElement('article');
proArticle.classList.add('article---pro--con', 'pro');
proArticle.innerHTML = `
<h3>Pros</h3>
<ul class="list---container pro_container"></ul>
<input type="text" value="" class="input_pro" placeholder="Enter a Pro and press enter..." />
`;
. . .
3. Print the List – The “Print” button should grab the current lists and format them for printing.
// Print functionality
const printButton = document.getElementById('js---print_contents');
printButton.addEventListener('click', function () {
window.print();
});
Adding the first set works flawlessly. Adding one list item each time with each list item filling the available space of its container. This means that later on, we can add some useful things to the styling. For example, style rule on the pseudo hover class or by selecting the last child list item.
We also have the function pressing enter on the keyboard perfectly put in place which adds to the ease of use of the app. Later on, it’s probably worth adding a button for mouse users but we can add that to a future version of the app.
Now… here’s where issues start to come in.
When we click on “add new set”, we do get a new set of article elements complete with the input and they do work the same way. However, they do seem to lose some of their style inheritance which means no vertical alignment
It’s an interesting job to work out what’s breaking the CSS because the document structure in the HTML seems to remain constant.
But I think I might have figured out what’s wrong.
Each set has 2 input boxes – one to enter the pros for a decision and the other for the cons.
They both have class attributes applied of input_pro. The second one should have a class attribute of input_con. When I check the script that ChatGPT provided me, I can see that it was ahead of the game and provided the correct class so that every time I click the “add new set” button, the correct classes will be added to the document tree.
const conArticle = document.createElement('article');
conArticle.classList.add('article---pro--con', 'con');
conArticle.innerHTML = `
<h3>Cons</h3>
<ul class="list---container con_container"></ul>
<input type="text" value="" class="input_con" placeholder="Enter a Con and press enter..." />
`;
section.appendChild(conArticle);
What I have to do is change that class manually in the original markup.
<article class="article---pro--con con">
<h3>Cons</h3>
<ul class="list---container con_container">
<li>fghg</li>
</ul>
<input type="text" value="" class="input_con" placeholder="Enter a Con and press enter...">
</article>
The only other problem is we now need to add that selector to our Sass files.
.input_pro,
.input_con {
display: block;
margin: 8px 0
}
This means we have much better vertical alignment of our elements in our CSS. The dynamic elements share much the same visual behaviour as the original ones.

I say “much the same”. Because it’s better but still not quite right.
There is a spacing discrepancy that doesn’t come from the styling. The main difference is that the new elements created with JavaScript are inserted after the page loads, it’s possible some inline or early-defined CSS may not be applied.
There are 2 main things to do to debug this issue.
Default Styles Applied by the Browser:
Browsers often apply their default styles (e.g., margins, padding, line height, etc.) to certain elements.
CSS for Dynamically Added Elements: There may be an issue with dynamic elements not inheriting the right CSS styles despite having the appropriate class or ID selectors in place.
It can be tricky when there’s a visible discrepancy, but the browser tools don’t immediately reveal it. And there are no changes in the document tree from static to dynamic. This issue I’m experiencing is a cosmetic one rather than one with functionality. Will come back to it with a fresh pair of Yes later. For now, we have the bones of a new functional application that I do look forward to enhancing and putting out into the wild.


