Select containers, then wrap what is inside each one.
Select the outer elements whose contents you want wrapped.
Pass HTML, a DOM element, a jQuery object, or a selector as the wrapper.
Or pass a function (1.4+) that returns a wrapper per element.
Use well-formed HTML with one innermost element for nested shells.
Piece
Required?
Role
Matched set
Yes
Outer elements (tags stay)
wrappingElement
Yes*
HTML / element / jQuery / selector
function(index)
Alt (1.4+)
Returns wrapper; this = current element
Pseudocode
Pseudocode
for each matched element el at index i:
if argument is a function:
wrapper = function.call(el, i)
else:
wrapper = clone(wrappingElement)
move all child nodes of el into the innermost wrapper
append that wrapper as the only child of el
return original matched set
Reference
Cheat Sheet
Keep these facts handy while wrapping contents.
Topic
Detail
Since
jQuery 1.2 (callback 1.4)
Result
Inner wrapper per matched element
Outer tag
Stays the same
vs wrap
.wrap() adds a parent outside
vs wrapAll
.wrapAll() = one shared outer parent
Callback
Once per element with index
HTML
Well-formed; one innermost node
Try it
Live Preview
Wrap paragraph contents in <b>, or reset.
Browser demo of .wrapInner() — same idea as the examples below.
Hello
cruel
World
Result
Ready — pick an action and Run
Code
jQuery Examples
Short, copy-ready snippets. Open DevTools Console, or use Try It Yourself for a live editor.
Build template.$("<span class='mark'>") is the pattern.
Clone. Each paragraph gets its own copy.
Wrap. Contents move into that span.
Outer. Each p still wraps the new span.
Edge Cases & Pitfalls
Check these before wrapping many containers.
html
Use well-formed HTML
Official guidance: closed tags only — e.g. "<div></div>", not broken fragments.
nest
One innermost element
Nested wrappers are fine, but there must be a single deepest container for the contents.
empty
Empty elements still get a wrapper
An empty match receives an empty inner shell — useful or surprising depending on intent.
xss
Untrusted HTML is unsafe
Do not build wrapper strings from URL params, cookies, or form fields without escaping.
Compatibility
Browser Support
.wrapInner() has been part of jQuery since 1.2. The function callback arrived in 1.4 and runs once per matched element.
✓ Stable · jQuery 1.2+
jQuery .wrapInner()
Supported in all browsers that run jQuery 1.2+. Prefer a current jQuery 3.x build for modern projects.
100%jQuery core method
Google ChromeAll versions · Desktop & Mobile
Full support
Mozilla FirefoxAll versions · Desktop & Mobile
Full support
Apple SafariAll versions · macOS & iOS
Full support
Microsoft EdgeAll versions · Chromium & Legacy
Full support
Internet ExplorerIE 6+ · Legacy environments
Full support
OperaAll modern versions
Full support
.wrapInner()Universal
Bottom line: Use when the outer tag must stay and only the contents need a new shell.
Analysis
Performance Notes
Approach
Cost
Best for
Few elements
Cheap
UI polish, emphasis tags
Callback per element
Moderate
Dynamic class shells
Huge sets + deep nests
Expensive
Avoid — wrap fewer nodes
Each match gets its own wrapper. Prefer .wrapAll() when you only need one shared outer container for the set.
Remember
Key Takeaways
Role: wrap contents inside each match; outer tag stays.
vs wrap:.wrap() adds a parent outside.
Callback: once per element with index.
HTML: well-formed, one innermost container.
One line:.wrapInner() adds a shell around what is inside an element without replacing the outer tag.
Frequently Asked Questions
.wrapInner() wraps the contents inside each matched element. The matched element tag stays as the outer node; children move into a new inner wrapper. Returns the original matched set. Available since jQuery 1.2; callback form since 1.4.
.wrap() adds a new parent outside the matched element. .wrapInner() keeps the matched element and wraps what is inside it.
.wrapInner() wraps contents inside each match separately. .wrapAll() wraps the whole set of matched elements in one shared outer parent.
Yes, since 1.4. The function runs once per matched element with the index argument; this is the current element. Return HTML or a jQuery/DOM structure.
No. Templates are cloned for each match. The original node stays where it is.
Select the inner wrapper and unwrap its contents, for example $('p').children('b').contents().unwrap() or unwrap the inner element itself when appropriate.
Use well-formed HTML with correctly closed tags, such as '<div></div>' or '<div><p></p></div>' with a single innermost element.