SharePoint person column formatting: avatars and people cards
Turn a person column into a compact card — initial, name, and a click-to-email link — or give a plain text name a consistent colored avatar.
A Person or Group column in SharePoint or Microsoft Lists shows a name and, in most views, a small profile photo. That's fine until you want more: the email one click away, a bigger and clearer avatar, or a name from a plain text column (an external contact, an imported spreadsheet) that has no profile at all. Column formatting JSON handles all of these.
The key thing to know is that a person column isn't text — it's an object with several properties: title (the display name), email, id, picture, sip, department, and jobTitle. Your JSON reaches into it with a dot, like [$AssignedTo.title]. Reference the column with no property and you won't get the name you expect.
Before and after
What the SharePoint person card JSON looks like
The generator produces JSON like the example below: a circle with the first letter of the name, then a two-line block with the name and a mailto link built from the email property:
{
"$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json",
"elmType": "div",
"inlineEditField": "[$AssignedTo]",
"style": { "display": "flex", "align-items": "center", "cursor": "pointer" },
"children": [
{
"elmType": "div",
"style": {
"width": "28px",
"height": "28px",
"border-radius": "50%",
"background-color": "=if([$AssignedTo.title] == '', '#c8c6c4', '#0078d4')",
"color": "=if([$AssignedTo.title] == '', '#323130', '#ffffff')",
"display": "flex",
"align-items": "center",
"justify-content": "center",
"font-size": "11px",
"font-weight": "700",
"margin-right": "8px"
},
"txtContent": "=if([$AssignedTo.title] == '', '–', substring([$AssignedTo.title], 0, 1))"
},
{
"elmType": "div",
"style": { "display": "flex", "flex-direction": "column", "line-height": "1.2" },
"children": [
{
"elmType": "span",
"txtContent": "=if([$AssignedTo.title] == '', 'Unassigned', [$AssignedTo.title])",
"style": { "font-weight": "600", "font-size": "12px" }
},
{
"elmType": "a",
"attributes": {
"href": "=if([$AssignedTo.email] == '', '', 'mailto:' + [$AssignedTo.email])",
"target": "_blank"
},
"txtContent": "[$AssignedTo.email]",
"style": { "font-size": "10px", "color": "#605e5c", "text-decoration": "none", "display": "=if([$AssignedTo.email] == '', 'none', 'inline')" }
}
]
}
]
}
Every reference to the person goes through a property. substring([$AssignedTo.title], 0, 1) takes the initial, [$AssignedTo.title] is the name, and the link's href is the string mailto: joined to [$AssignedTo.email]. One caveat from Microsoft's own documentation: title is the display name by default, but if the column's "Show field" setting was changed to, say, Department, then title returns the department instead.
The object also carries a picture property — the URL of the profile photo — which an img element could show. The template uses a colored initial on purpose: it needs no extra request, never shows a broken-image icon, and looks identical for guests and external users who have no photo.
Names in a text column
If your names live in a single line of text column — a vendor contact, a name typed by hand, an import — there's no person object to read from. The Initials Avatar template works on plain text: it takes the first letter, picks a color from that letter so the same person is always the same color, and shows Unassigned with a grey circle when the cell is empty.
How to apply it
- Open the generator and pick the Person Card template (or Initials Avatar for a text column).
- Enter your column's internal field name — see the note below.
- Click Copy.
- In SharePoint: Column settings → Format this column → Advanced mode.
- Delete what's in the box, paste, click Preview, then Save.
AssignedTo internally. See the internal field name guide to find yours.
Common questions
Which properties of a person column can I use?
title, email, id, picture, sip, department, and jobTitle. Reference one with a dot — [$AssignedTo.title] for the display name, [$AssignedTo.email] for the address. Using the bare column without a property does not give you the name.Does it work for a column that allows multiple people?
[$AssignedTo.title] only resolves for a single value. Showing several people needs a forEach loop in the JSON, which the Person Card template does not include — treat it as a starting point and add forEach by hand.Can I show the real profile photo instead of an initial?
picture property with the profile photo URL, so an img element can display it. The template uses a colored initial instead because it renders instantly, needs no image request, and looks the same for guests who have no photo.