An attribute is the most basic level of stuff that a CMS database holds. It consists most fundamentally of two things:
A piece of data.
A label for that data.
In practice, attributes hold a bunch of other information (e.g., an internal name, a user-facing label, a datatype, and a UI interface). All those things are important for how your website is built, but they aren’t as important here, so we’re going to ignore them.
What matters for our purposes is that an attribute is a data point together with the full set of things stored with that data point (datatype, internal name, user-facing label, etc.).
For a content strategist or a developer, content type is a technical term that refers to a specific set of content management system functionality. Roughly speaking, a content type (in this sense) is a set of attributes (or fields) that are collected into a single entity that is then published on the website.
Your CMS connects to a database, which is sort of like a really fancy spreadsheet. Built properly, your CMS will store each functional piece of content—an attribute in CMS lingo—in its own spreadsheet column. Better still, it’ll give each column a name that tells the CMS what that content does. That opens up a whole new world of possibilities.
More confusingly, items with different rhetorical functions can have identical sets of attributes. This is most evident for legacy content that is posted as PDF files. A brief and a working paper have very different rhetorical functions. But the rhetoric is entirely contained in the PDF. The structural bits stored in the CMS are usually identical.