jQuery .wrapInner() Method

Beginner
⏱️ 10 min read
📚 Updated: Jul 2026
🎯 5 Examples
🚀 5 Try-it labs
DOM methods

What You’ll Learn

The .wrapInner() method inserts a new wrapper around all contents inside each matched element — the outer tag stays in place. This tutorial covers syntax since 1.2, callback form since 1.4, comparisons with .wrap(), .wrapAll(), and .unwrap(), the official yellow-paragraph demo, and five practical try-it examples.

01

.wrapInner()

Inner wrap

02

Contents

Child nodes

03

vs .wrap()

Inside not out

04

Callback

Per element

05

Clone

Not moved

06

Since 1.2

Core API

Introduction

Sometimes you need an inner container without changing the outer element tag — a padding shell inside a card, a styled frame around paragraph text while keeping the <p> semantic tag, or a plugin that expects content nested one level deeper. When the matched element should stay but its children need grouping, jQuery provides .wrapInner().

Available since jQuery 1.2, .wrapInner() wraps all child nodes inside each matched element separately. Pass an HTML string, selector, DOM element, or jQuery object. Since jQuery 1.4, a callback can return a custom inner wrapper per element — this refers to the current matched DOM node. This differs from .wrap(), which adds a parent outside the element.

The wrapping structure must contain exactly one innermost element where child nodes are placed. jQuery clones DOM nodes and jQuery objects rather than moving the original template. Browse the jQuery DOM hub for related manipulation methods.

Understanding the .wrapInner() Method

.wrapInner( wrappingElement ) or .wrapInner( function ) creates a new wrapper inside each matched element around all its contents. jQuery clones the wrapper structure for every match — three paragraphs wrapped with .wrapInner( "<div class='inner'>" ) produce three separate <p><div class="inner">…</div></p> groups while each <p> tag remains the outer node.

The return value is the same jQuery collection (for chaining). All child nodes — text, elements, and comments — are grouped together inside the new wrapper. When you pass a DOM node or jQuery object, jQuery clones it rather than moving the original.

💡
Beginner Tip

Before: <p>Hello</p>. After $("p").wrapInner( "<div class='inner'>" ): <p><div class="inner">Hello</div></p>. Compare with $("p").wrap( "<div>" ), which adds a div parent around the paragraph instead of wrapping content inside it.

📝 Syntax

jQuery .wrapInner() supports two forms:

Wrap contents with HTML string, selector, element, or jQuery object — since 1.2

jQuery
.wrapInner( wrappingElement )
  • wrappingElement — HTML string, selector, DOM element, or jQuery object.
  • Structure must have one innermost element; can include nested outer layers.
  • Each matched element gets its own copy of the inner wrapper.

Wrap contents with callback — since 1.4

jQuery
.wrapInner( function )
  • Callback runs once per matched element; this refers to the current DOM element.
  • Return an HTML string or jQuery object to use as the inner wrapper.
  • Use for dynamic wrappers — e.g. a class derived from element index.

Return value

  • Returns the same jQuery collection that was wrapped.
  • Chain further manipulation on the matched elements.

Official wrapInner paragraph demo

The jQuery API documentation wraps paragraph contents in an inner div with yellow background:

jQuery
$( "p" ).wrapInner( "<div class='inner'></div>" );



// CSS for the official demo:

// p { background: yellow; }

// div.inner { border: 2px solid orange; }

⚡ Quick Reference

GoalCode
Wrap contents of each match in a div$("p").wrapInner("<div>")
Wrap contents with styled inner shell$("p").wrapInner("<div class='inner'>")
Add outer parent around each element$("p").wrap("<div>")
Dynamic inner wrapper via callback$("p").wrapInner(function(i){ return "<div class='item-" + i + "'>"; })
Wrap all matches in one outer container$("p").wrapAll("<div>")
Remove inner wrapper$("p").children(".inner").contents().unwrap()

📋 .wrapInner() vs .wrap() vs .wrapAll() vs .unwrap()

Four related DOM structure APIs — pick the right wrapping strategy.

.wrapInner()
wrap contents

Insert a wrapper inside the matched element around all child nodes

.wrap()
add parent

Insert a wrapper around each matched element separately

.wrapAll()
one wrapper

Wrap the entire collection together in a single outer parent

.unwrap()
remove parent

Strip the immediate parent — inverse of wrap and wrapAll

Examples Gallery

Examples 1–5 follow the official jQuery API documentation and common production patterns. Use DevTools or the Try-it links to run each snippet in the browser.

📚 Getting Started

Official jQuery inner div demo and wrap vs wrapInner contrast.

Example 1 — Official Demo: Wrap Paragraph Contents in an Inner Div

Wrap all contents inside each paragraph in a <div class="inner"> — yellow background on the outer <p>, orange border on the inner div.

jQuery
$( "p" ).wrapInner( "<div class='inner'></div>" );



// CSS for the official demo:

// p { background: yellow; }

// div.inner { border: 2px solid orange; }
Try It Yourself

How It Works

.wrapInner( "<div class='inner'>" ) inserts a new div inside every matched paragraph, grouping all child nodes together. The outer <p> tag is unchanged. Each match receives a separate copy of the inner wrapper.

Example 2 — .wrap() vs .wrapInner() Contrast

The same paragraph element shows the key difference — outer parent versus inner content wrapper.

jQuery
// .wrap() — adds parent OUTSIDE the p tag

$( "#a p" ).wrap( "<div class='outer'>" );

// Result: <div class="outer"><p>Hello</p></div>



// .wrapInner() — adds wrapper INSIDE the p tag

$( "#b p" ).wrapInner( "<div class='inner'>" );

// Result: <p><div class="inner">Hello</div></p>
Try It Yourself

How It Works

.wrap() places the matched element inside a new parent. .wrapInner() keeps the matched element as the outer node and wraps its contents instead. This is the most common source of confusion between the two APIs.

📈 Practical Patterns

Card inner padding shells, callback wrappers, and DOM element cloning.

Example 3 — Card Inner Padding Shell Without Changing Outer Tag

Add an inner padding container inside each .card while preserving the outer card element for layout and semantics.

jQuery
$( ".card" ).wrapInner( "<div class='card-body'></div>" );



// Before: <article class="card"><h3>Title</h3><p>Text</p></article>

// After:  <article class="card">

//           <div class="card-body"><h3>Title</h3><p>Text</p></div>

//         </article>



// CSS: .card-body { padding: 1rem; }
Try It Yourself

How It Works

.wrapInner() groups every child node inside the new div without altering the outer <article> tag. Ideal when CSS grid, flex, or semantic HTML requires the outer element to stay fixed while inner content gets a padding or scroll container.

Example 4 — Callback wrapInner With Dynamic Class From Index

Return a custom inner wrapper per element using a function — since jQuery 1.4. this refers to the current matched element.

jQuery
$( "p" ).wrapInner( function( index ) {

  return "<div class='inner item-" + index + "'></div>";

});



// First p  → <p><div class="inner item-0">…</div></p>

// Second p → <p><div class="inner item-1">…</div></p>
Try It Yourself

How It Works

The callback receives the zero-based index and the raw DOM element. Return value becomes the inner wrapper for that specific match. Unlike .wrapAll(), where the callback runs once, .wrapInner() evaluates the function per element.

Example 5 — wrapInner With document.createElement or jQuery Object

Pass a DOM node or jQuery collection — jQuery clones the structure for each match without moving the original.

jQuery
// Using document.createElement

var shell = document.createElement( "div" );

shell.className = "inner";

$( "p" ).wrapInner( shell );



// Using a jQuery object — also cloned, not moved

var $shell = $( "<div class='inner'></div>" );

$( "p" ).wrapInner( $shell );



// Original shell variable stays in memory; clones used per match
Try It Yourself

How It Works

Unlike .append(), which moves nodes, .wrapInner() clones the supplied element for each match. Reuse one template variable across many elements without it disappearing from the DOM after the first wrap.

🚀 Common Use Cases

  • Inner padding shells — add a .card-body or .content-inner div inside cards without changing the outer tag.
  • Semantic preservation — wrap paragraph text inside a styled div while keeping the <p> element for accessibility.
  • Plugin requirements — nest content one level deeper inside the structure a third-party script expects.
  • Scroll containers — insert an inner overflow wrapper inside a fixed-height panel.
  • Dynamic inner styling — callback form assigns per-element classes on the inner wrapper from index or data.
  • Grouped child nodes — bundle mixed text and element children inside one inner container per match.

🧠 How .wrapInner() Wraps Contents Inside Matched Elements

1

Match target elements

jQuery collection points at outer nodes whose contents will be wrapped.

Select
2

Build wrapper structure

Parse HTML string, clone DOM element, or evaluate callback return value.

Clone
3

Insert inside each match

Each matched element gets its own copy of the inner wrapper inserted as a direct child.

Per element
4

Group all child nodes

Every child node moves inside the inner wrapper; outer tag stays; collection returned for chaining.

📝 Notes

  • Available since jQuery 1.2 — callback form added in jQuery 1.4.
  • Wraps all contents inside each matched element separately (use .wrapAll() for one shared outer wrapper).
  • Outer matched element tag stays in place; new wrapper is inserted inside it.
  • Wrapper HTML must contain exactly one innermost element; nested outer tags are allowed.
  • Callback runs once per matched element; this refers to the current DOM element.
  • DOM elements and jQuery objects are cloned, not moved from their source location.
  • Remove inner wrappers with .children().contents().unwrap() or similar patterns.

Browser Support

.wrapInner() has been part of jQuery since 1.2+, with the callback form since 1.4+. It relies on standard DOM parent-child insertion. Works in all browsers supported by your jQuery build — IE6+ through modern evergreen browsers in legacy jQuery versions, and all current browsers in jQuery 3.x and 4.x.

jQuery 1.2+

jQuery .wrapInner()

Universal inner-content wrapping API across jQuery 1.x, 2.x, 3.x, and 4.x. No browser-specific polyfills required — jQuery normalizes wrapper insertion and cloning. Pair with .children().contents().unwrap() to remove inner wrappers.

100% With jQuery loaded
Google Chrome All versions · Desktop & Mobile
Full support
Mozilla Firefox All versions · Desktop & Mobile
Full support
Apple Safari All versions · macOS & iOS
Full support
Microsoft Edge All versions · Chromium & Legacy
Full support
Internet Explorer IE 6+ · Legacy environments
Full support
Opera All modern versions
Full support
.wrapInner() Universal

Bottom line: Default choice for wrapping contents inside each matched element without changing the outer tag.

Conclusion

The jQuery .wrapInner() method inserts a new wrapper around all contents inside each matched element. Pass an HTML string, DOM node, jQuery object, or callback. The outer element tag stays in place while child nodes move inside the new inner container — the opposite of .wrap(), which adds a parent outside.

Choose .wrap() to add an outer parent around each element, .wrapAll() to group siblings under one shared wrapper, and .unwrap() to remove outer parents. Next up: inserting content with .append().

💡 Best Practices

✅ Do

  • Use .wrapInner() when the outer element tag must stay unchanged
  • Ensure wrapper HTML has one innermost empty element
  • Use the callback form when inner wrapper attributes vary per element
  • Use .wrap() when you need an outer parent around the element
  • Remove inner wrappers with .children().contents().unwrap()

❌ Don’t

  • Use .wrapInner() when you need a parent outside the element
  • Confuse .wrapInner() with .wrap() or .wrapAll()
  • Assume a passed DOM element is moved — it is cloned per match
  • Expect .unwrap() on the outer element to remove inner wrappers
  • Provide wrapper HTML with multiple innermost empty elements

Key Takeaways

Knowledge Unlocked

Five things to remember about .wrapInner()

The wrap-contents-inside API — one inner wrapper copy per matched element.

5
Core concepts
02

vs wrap

Inside not out

Compare
× 03

Per match

Separate copy

Each
ƒ 04

Callback

Since 1.4

Dynamic
05

Remove

.unwrap inner

Reverse

❓ Frequently Asked Questions

.wrapInner() inserts a new wrapper element around all contents inside each matched node. The matched element tag stays in place; child nodes are grouped together inside the new inner wrapper. It returns the same jQuery collection. Available since jQuery 1.2 for HTML strings, selectors, DOM elements, and jQuery objects; the callback form since 1.4.
.wrap() adds a new parent outside the matched element — the element moves inside the wrapper. .wrapInner() keeps the matched element as the outer node and wraps its contents instead. Use wrap to add a div around each paragraph; use wrapInner to wrap the text inside a paragraph without changing the outer p tag.
.wrapInner() wraps contents inside each matched element separately — three paragraphs each get their own inner wrapper. .wrapAll() wraps all matched elements together in one shared outer parent. Use wrapInner for per-element inner padding shells; use wrapAll when siblings should share one container.
Since jQuery 1.4, pass a function that returns the wrapper HTML or jQuery object. The callback runs once per matched element — unlike .wrapAll(), which runs once for the entire collection. Inside the function, this refers to the current DOM element being processed.
Select the inner wrapper and promote its contents up one level. A common pattern is $("p").children(".inner").contents().unwrap() or $(".card").children().contents().unwrap() when the wrapper is the sole direct child. This moves child nodes out of the inner div while keeping the outer matched element intact.
Yes. Pass an HTML string, selector, DOM element, or jQuery object. jQuery clones the structure for each matched element — the original node is not moved from its source location. Use document.createElement or $("<div>") when you need a reusable template.
Did you know?

jQuery added .wrapInner() in version 1.2 — alongside .wrapAll() — to complete the wrapping API family started by .wrap() in 1.0. The callback form arrived in 1.4. The official yellow-paragraph demo exists specifically to show that the outer <p> tag stays while only its contents move inside the new div. Before wrapInner existed, developers manually created inner divs, moved child nodes with appendChild, and re-inserted them — a tedious pattern for batch operations across many elements.

Next: jQuery .append() Method

Insert HTML, DOM nodes, or jQuery objects as the last child of matched elements.

.append() tutorial →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

6 people found this page helpful