diff --git a/docs/element-properties.mdx b/docs/element-properties.mdx
index 46f3019..5f5f88b 100644
--- a/docs/element-properties.mdx
+++ b/docs/element-properties.mdx
@@ -23,7 +23,7 @@ ele.tagName // "IMG"
:::note Text nodes don't have `tagName`
-Text nodes are not element, so they don't have any tagName. To identify the type of node, use `.nodeType`. For text nodes, `nodeType` is `3`- same as the constant `Node.TEXT_NODE`.
+Text nodes are not element, so they don't have any tagName. To identify the type of node, use `.nodeType` property. For text nodes, `nodeType` is `3` - same as the constant `Node.TEXT_NODE`.
:::
@@ -67,7 +67,7 @@ container.childNodes // [text, div, text]
Read more about [other types of nodes](https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType) and how [whitespace works in html](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Whitespace).
:::
-### 2. .children
+### 2. children
`Element.children: HTMLCollection`
@@ -101,7 +101,7 @@ for (let i = 0; i < children.length; i++) {
-### 3. .childNodes
+### 3. childNodes
`Element.childNodes: NodeList`
@@ -129,6 +129,71 @@ childNodes // NodeList [text, span, text]
+### 4. firstChild + nextSibling
+
+`Element.firstChild: Node`
+
+
+This property returns the element's **first child** node in the tree. If the node has no children, then it returns `null`.
+
+`Element.nextSibling: Node`
+
+This property returns the node immediately **after the current one** in their parent's childNodes.
+
+```jsx
+
+
+var eleA = document.getElementByID("A")
+
+var eleB = eleA.firstChild //
+var eleC = eleB.nextSibling //
+eleC.nextSibling // null
+```
+
+There is also a similar `previousSibling` property, which returns the previous node. Also, there are element-only variant for all these properties like `firstElementChild`, `nextElementSibling`, etc.
+
+
+
+:::note Easier traversal
+
+This allows accessing the DOM tree in [Left-child right-sibling](https://en.wikipedia.org/wiki/Left-child_right-sibling_binary_tree) (LCRS) form, which is more memory efficient for usual traversal.
+
+#### How do you implement **dom traversal**?
+
+The typical approach is to use a queue, push all children to the queue, pop them one-by-one and visit them. This requires **extra memory** because of the queue data structure which holds all the *next items to visit*.
+But with the LCRS form, you always have access to the next item **without using extra space**. If current element has child, visit `.firstChild`. Then visit next node using `.nextSibling`.
+
+```js
+// 1. Typical approach
+var queue = [root]
+while (queue.length > 0) {
+ const item = queue.shift();
+ console.log(item);
+ if (item.hasChildNodes()) {
+ queue = Array.from(item.childNodes).concat(queue)
+ }
+}
+
+// 2. LCRS approach
+function traverse(item) {
+ if (item === null) {
+ return;
+ }
+
+ console.log(item);
+ traverse(item.firstChild)
+ traverse(item.nextSibling)
+}
+traverse(root.firstChild)
+```
+:::
+
+
+
+