Complete CSS Course Module 12: Intermediate: CSS Components and UI Patterns

CSS User Interface Properties: resize, cursor, caret-color and user-select

  • Beginner
  • Lesson 12.6
  • 6 min read
  • 56 of 77 in the course

In short

CSS user interface properties control how people interact with a page: resize, cursor, caret-color, user-select, pointer-events, scrollbar colors and accent-color. What are CSS user interface properties? Most CSS changes how a page looks.

CSS user interface properties control how people interact with a page: resize, cursor, caret-color, user-select, pointer-events, scrollbar colors and accent-color.

What are CSS user interface properties?

Most CSS changes how a page looks. A small group of properties changes how it feels to use: what the mouse pointer looks like, whether a box can be resized, whether text can be selected, and the color of the blinking text cursor. These are the user interface properties. Small details like these are like the handles on doors: people only notice them when they are wrong.

You have already seen cursor: pointer on buttons and accent-color on checkboxes in the Styling Forms and Buttons lesson. Here we look at the full set.

The resize property: let users resize a textarea or box

The resize property decides whether the user can drag the corner of an element to change its size. By default, a <textarea> can be resized in both directions.

<label for="msg">Your message</label>
<textarea id="msg" class="message" rows="5"></textarea>

<div class="note-box">Drag my bottom-right corner to make me wider or taller.</div>
.message {
  width: 100%;
  min-height: 120px;
  max-height: 400px;
  resize: vertical;
}

.note-box {
  width: 250px;
  height: 120px;
  padding: 1rem;
  border: 1px dashed #6b7280;
  overflow: auto;
  resize: both;
}

The textarea can now only be made taller or shorter, never wider, so it can't break your layout. min-height and max-height set limits on how far it can go. The dashed <div> gets a small drag handle in its corner and can be resized both ways.

ValueMeaning
noneCan't be resized
bothWidth and height
horizontalWidth only
verticalHeight only
block / inlineAlong the block or inline direction (follows the writing mode)

Common mistake: Adding resize: both to a <div> and nothing happens. resize only works when overflow is something other than visible, for example auto or hidden. Textareas already have this, but divs need overflow: auto.

The cursor property: change the mouse pointer

The cursor property sets the mouse pointer shape when it is over an element. The right cursor tells the user what will happen before they click.

ValueLooks likeUse it for
autoBrowser decidesThe default
defaultNormal arrowThings that are not clickable
pointerPointing handButtons and clickable cards
textI-beamSelectable text, inputs
moveFour arrowsSomething you can drag anywhere
grab / grabbingOpen / closed handDraggable items, before and during dragging
not-allowedCircle with a lineDisabled buttons
waitSpinner or hourglassThe whole page is busy
progressArrow with a spinnerBusy, but you can still click
helpArrow with a question markExtra info is available
crosshairThin crossPrecise picking, drawing tools
zoom-in / zoom-outMagnifying glassImages that zoom
col-resize / row-resizeArrows with a barDragging column or row dividers
noneHiddenGames, custom cursors (use rarely)
.product-card { cursor: pointer; }
.gallery img { cursor: zoom-in; }
.draggable { cursor: grab; }
.draggable:active { cursor: grabbing; }
abbr[title] { cursor: help; }

.paint-area {
  cursor: url("brush.png") 4 28, crosshair;
}

Hover each element to see a different pointer: a hand on the card, a magnifier on gallery images, an open hand on the draggable item that closes while you hold the mouse button. For .paint-area, the browser uses your own brush.png image. The two numbers 4 28 are the "hot spot", the exact pixel that does the clicking. After the comma, crosshair is a fallback if the image fails to load; a keyword fallback is always required after a url().

Tip: Don't put cursor: pointer on everything. Use it for things that act when clicked. Normal text should keep the I-beam so people know they can select it.

caret-color and user-select

The caret is the blinking line that shows where you are typing. caret-color changes its color, which is a nice touch for a brand color or a dark theme.

.search-input {
  caret-color: #e11d48;
}

.code-editor {
  background: #0f172a;
  color: #e2e8f0;
  caret-color: #facc15;
}

Click into the search field and the blinking line is pink-red instead of black. In the dark editor, a yellow caret is easy to spot on the dark background.

user-select controls whether people can select (highlight) text.

<button class="btn" type="button">Add to cart</button>
<p>Your coupon code: <code class="coupon">SPRING-25</code></p>
.btn {
  user-select: none;
}

.coupon {
  -webkit-user-select: all; /* older Safari */
  user-select: all;
}

Double-click the button text quickly: nothing gets highlighted, so fast clicks don't select the label by accident. Click once on the coupon code and the whole code is selected at once, ready to copy, instead of just one word.

ValueMeaning
autoNormal behavior (default)
noneText can't be selected
textText can be selected
allOne click selects the whole element

Note: Never use user-select: none on articles or normal content to "protect" your text. It doesn't stop copying (anyone can view the source), and it annoys people who select text to translate it, look up a word or read along.

pointer-events and custom scrollbars

pointer-events: none makes the mouse "pass through" an element, as if it were made of glass. Clicks, hovers and the cursor go to whatever is behind it.

.hero {
  position: relative;
}

.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgb(0 0 0 / 0.6), transparent);
  pointer-events: none;
}

The dark gradient overlay sits on top of the hero section, but you can still click the links and buttons under it. Without pointer-events: none, the overlay would catch every click. This is the same trick we used for tooltips. Remember that pointer-events: none only affects the mouse and touch: keyboard users can still Tab to a link, so it is not a way to disable something.

You can also style scrollbars with two standard properties. scrollbar-color takes two colors: the thumb (the part you drag) and the track (the line it moves along). scrollbar-width takes auto, thin or none.

.chat-messages {
  height: 300px;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: #94a3b8 #f1f5f9;
}

The chat box gets a thin grey scrollbar on a very light track. These properties work in Chrome, Edge and Firefox, and newer Safari versions support scrollbar-width; browsers without support simply show the normal scrollbar, so it is safe to use. Use scrollbar-width: none very carefully: hiding the scrollbar can make people miss that there is more content.

Finally, accent-color colors checkboxes, radio buttons, range sliders and progress bars with one line, for example accent-color: #16a34a;. You learned it in the Styling Forms and Buttons lesson. See the full list of UI properties on MDN: CSS basic user interface.

Practice exercise

Build a small "Notes" app layout: a <textarea> that can only grow taller (between 150px and 500px), a pink caret, a "Copy note ID" line where one click selects the whole ID, a draggable-looking note card with grab and grabbing cursors, and a notes list with a thin, colored scrollbar.

Hint: you need resize: vertical, caret-color, user-select: all, cursor: grab plus :active { cursor: grabbing; }, and scrollbar-width with scrollbar-color on a box with a fixed height and overflow-y: auto.

Key takeaways

  • resize lets users resize textareas and boxes, but only when overflow is not visible.
  • cursor tells people what will happen: pointer for clickable, not-allowed for disabled, grab for draggable.
  • caret-color colors the typing cursor; user-select controls text selection, so use none only on UI controls.
  • pointer-events: none lets clicks pass through overlays, but it does not block keyboard users.
  • scrollbar-color, scrollbar-width and accent-color style built-in browser parts with a single line.