Tangy is building your next step
Shaping the lesson around what you want to make.
Tangy is building your next step
Shaping the lesson around what you want to make.
Computer Science
You already know how to structure HTML and style a page with CSS, so you will use those skills immediately instead of starting over. Step by step, you will add the JavaScript you need to turn a static plant page into a browser-based simulator where changing light, water, and carbon dioxide changes the plant's photosynthesis results and explanation.
Build it yourself, get guided when you are stuck, and leave with proof you can actually show.
Turn a Familiar Page into a Plant Simulator
2 lessonsCreate the simulator's semantic HTML and visual layout using the HTML structure and CSS selector skills you already have. By the end, the project is a polished static page ready for behavior.
Give the Page Its First Behavior
3 lessonsLearn only the JavaScript foundations needed to read the page and change it. The learner crosses from static HTML/CSS into behavior through small, visible interactions rather than a large new setup.
Model What Photosynthesis Needs
4 lessonsBuild a small, understandable model rather than pretending to reproduce a real laboratory calculation. The simulator will combine several conditions, identify limiting resources, and explain the result.
Make Every Control Drive the Simulation
4 lessonsConnect the complete interface to the model and create feedback that makes cause and effect easy to observe. The learner gets a fully interactive simulator before adding visual polish.
Make the Science and Interface Clear
3 lessonsTurn the working model into something another person can understand and use. The simulator will communicate the photosynthesis story through labels, explanations, and resilient interface behavior.
Finish and Demonstrate the Simulator
2 lessonsConsolidate the code, remove confusion, and prepare a short demonstration that proves both the programming and the photosynthesis model work.
Public lesson
You’re building the plant simulator’s interface before adding its behavior. Today, make the page readable to a person and predictable for the JavaScript you’ll add next.
Work in the component that currently renders your simulator screen, probably App.jsx or a page component.
Tasks
Before coding, identify these five regions in your existing screen:
The plant display and the two panels are the main regions JavaScript will need to find later. Give each one a clear semantic element rather than placing everything inside anonymous <div> elements.
Tasks
Adapt this skeleton to your project. Keep your existing styling setup, but replace the placeholder comments with your own content.
return (
<main>
<header>
<h1>Plant Simulator</h1>
{/* Add a short subtitle for the simulator */}
</header>
<section aria-labelledby="plant-display-heading">
<h2 id="plant-display-heading">Plant</h2>
{/* Add the plant image, illustration, or plant placeholder here */}
</section>
<section aria-labelledby="inputs-heading">
<h2 id="inputs-heading">Inputs</h2>
<form>
<fieldset>
<legend>Environmental conditions</legend>
{/* Add the light control here */}
{/* Add the water control here */}
{/* Add the carbon dioxide control here */}
</fieldset>
</form>
</section>
<section aria-labelledby="outputs-heading">
<h2 id="outputs-heading">Outputs</h2>
{/* Add the simulator result values here */}
</section>
<aside aria-labelledby="explanation-heading">
<h2 id="explanation-heading">How photosynthesis works</h2>
{/* Add two or three sentences of explanation */}
</aside>
</main>
);
return (
<main>
<header>
<h1>Plant Simulator</h1>
{/* Add a short subtitle for the simulator */}
</header>
<section aria-labelledby="plant-display-heading">
<h2 id="plant-display-heading">Plant</h2>
{/* Add the plant image, illustration, or plant placeholder here */}
</section>
<section aria-labelledby="inputs-heading">
<h2 id="inputs-heading">Inputs</h2>
<form>
<fieldset>
<legend>Environmental conditions</legend>
{/* Add the light control here */}
{/* Add the water control here */}
{/* Add the carbon dioxide control here */}
</fieldset>
</form>
</section>
<section aria-labelledby="outputs-heading">
<h2 id="outputs-heading">Outputs</h2>
{/* Add the simulator result values here */}
</section>
<aside aria-labelledby="explanation-heading">
<h2 id="explanation-heading">How photosynthesis works</h2>
{/* Add two or three sentences of explanation */}
</aside>
</main>
);
Use <section> for the plant, inputs, and outputs because each is a named part of the simulator. The <aside> is suitable for the supporting explanation.
Tasks
Run the app and confirm:
<h1><h2>If a section heading is missing, add it before moving on. Those headings will also make the page easier to navigate with assistive technology.
Tasks
Inside the <fieldset>, create one labeled control for each environmental input:
Use a <label> connected to each control with matching htmlFor and id values. In JSX, remember that the attribute is htmlFor, not for.
Use this as a pattern, but change the names and values for the other controls yourself:
<div>
<label htmlFor="light-input">Light</label>
<input
id="light-input"
name="light"
type="range"
min="0"
max="100"
defaultValue={/* choose an initial value */}
/>
</div>
<div>
<label htmlFor="light-input">Light</label>
<input
id="light-input"
name="light"
type="range"
min="0"
max="100"
defaultValue={/* choose an initial value */}
/>
</div>
Tasks
Give the controls stable, descriptive IDs such as:
light-inputwater-inputcarbon-dioxide-inputThe ID names are not for styling. They give later JavaScript an unambiguous way to read the controls.
For now, use type="range" for all three. Choose sensible ranges for the simulator and display a unit or description beside each control if the meaning is not obvious.
Tasks
In the browser:
Then inspect the rendered HTML and verify that every input has:
idnameTasks
Add the plant visual inside the plant section. If you already have an image or plant component, use it. If not, use a temporary placeholder that makes the region visible.
For an image, include useful alternative text:
<img
src={/* use your existing plant image source */}
alt="A green plant used in the simulator"
/>
<img
src={/* use your existing plant image source */}
alt="A green plant used in the simulator"
/>
If the visual is decorative and the surrounding text already explains it, use an empty alt value instead. Don’t leave alt out.
Tasks
Add a stable target to the element that JavaScript may update later. For example, your plant visual might use:
<figure id="plant-display">
{/* Put the plant visual here */}
<figcaption>{/* Describe the current plant state */}</figcaption>
</figure>
<figure id="plant-display">
{/* Put the plant visual here */}
<figcaption>{/* Describe the current plant state */}</figcaption>
</figure>
Choose the element that best represents the whole display; don’t add IDs to every wrapper.
Tasks
Inspect the page and confirm:
alt textTasks
The outputs panel should show where calculated results will appear later. Include at least three outputs related to the simulator, such as:
Use <output> for values that will be calculated from the inputs. Give each output a stable ID and a readable label.
Use this partial pattern for one result, then create the others:
<p>
<span>Photosynthesis rate:</span>{" "}
<output id="photosynthesis-output">
{/* Add a temporary starting value and unit */}
</output>
</p>
<p>
<span>Photosynthesis rate:</span>{" "}
<output id="photosynthesis-output">
{/* Add a temporary starting value and unit */}
</output>
</p>
Do not make the output IDs depend on their visual position. A future handler should be able to target photosynthesis-output directly.
Tasks
The outputs panel should display a readable value for every result, even though the numbers are still static.
Then inspect the page and confirm each <output> has:
Tasks
Add two or three short sentences in the explanation area. Include:
Keep this explanation separate from the controls and results. It supports the simulator but is not itself an input or output.
Tasks
Read the explanation without looking at the controls. It should explain what the simulator is modeling, not just repeat the section title.
Tasks
Use the browser’s element inspector to verify the final outline. You should be able to find:
main
├── header
│ └── h1
├── section
│ └── h2 Plant
├── section
│ └── h2 Inputs
│ └── form
│ └── fieldset
│ └── legend
├── section
│ └── h2 Outputs
└── aside
└── h2 How photosynthesis works
main
├── header
│ └── h1
├── section
│ └── h2 Plant
├── section
│ └── h2 Inputs
│ └── form
│ └── fieldset
│ └── legend
├── section
│ └── h2 Outputs
└── aside
└── h2 How photosynthesis works
Your exact nesting may differ slightly, but the major regions should be present and named.
Tasks
Finally, test keyboard access:
Tab repeatedly.Leave the controls static for now. In the next behavior step, JavaScript can use the IDs and form structure you created to read the environmental values and update the outputs.
6 modules · 18 lessons
Turn a Familiar Page into a Plant Simulator
Give the Page Its First Behavior
Model What Photosynthesis Needs
Make Every Control Drive the Simulation
Make the Science and Interface Clear
Finish and Demonstrate the Simulator
Learn by building your own version.
Remix this public project to open the workspace, follow the guided build, and let the AI mentor teach you through the work instead of doing it for you.