Best Practice for Customising Component Styling in Ionic 4 - css

I am looking for best practice for changing component styling in Ionic 4, such as font size. I've read many sources but not clear on what the best approach is.
As I understand it, there is an SCSS file for each component that can be used to set styling for that component, and global.scss for global changes.
Are there any special considerations here? For example, is using element names appropriate or should classes be preferred?
What about when the styling varies between platforms? Is that best done with something like...
ion-card-header {
.ios & {
}
.md & {
}
}
To change globally, add it to the global SCSS?
Also how to work appropriately with CSS variables.
Looking for thoughts and best practices please, and any considerations special to the structure of Ionic 4.

I am having a go at answering this myself, to collect the information I have been looking at.
Utility Attributes - text-wrap, no-padding etc.
Ionic 4 includes a number of utility attributes that can be used to modify elements where they are available. Examples include text-wrap or padding-start.
These can be applied to any element, to adjust the styling by using an attribute. This is the preferred approach for changes that only apply to a single case, and would not benefit from a rule.
The utilities include:
Text Modification
text-center, text-wrap, text-capitalize etc.
Element Placement
float-left, float-end etc.
Content Space
padding-start (adds 16px padding at start), no-padding, margin-bottom etc.
Flex Properties
justify-content-evenly, align-items-baseline, nowrap, align-self-center etc.
For the text modification and element placement attributes, they have responsive versions, such as text-lg-center or float-sm-end.
CSS Variables - --color, --padding-start etc.
Ionic 4 is built using CSS Variables (more on CSS Variables), replacing SCSS variables and enabling runtime changes.
Global CSS Variables - --ion-color-primary, --ion-color-primary-contrast etc.
Colour Variables
--ion-color-primary, --ion-color-primary-contrast etc.
Application Variables
--ion-font-family, --ion-grid-padding-md etc.
These are described in more detail below.
Global Colour CSS Variables
Theme colours should be used for any colour that is used throughout your application. Ionic 4 provides 9 theme colours out of the box, which can be used to change the colour of many components. Examples include:
<ion-button>Default</ion-button>
<ion-button color="primary">Primary</ion-button>
<ion-button color="secondary">Secondary</ion-button>
<ion-button color="tertiary">Tertiary</ion-button>
<ion-button color="success">Success</ion-button>
<ion-button color="warning">Warning</ion-button>
<ion-button color="danger">Danger</ion-button>
<ion-button color="light">Light</ion-button>
<ion-button color="medium">Medium</ion-button>
<ion-button color="dark">Dark</ion-button>
Modifying Colour Variables
You should set all of appropriate variables when changing a colour, such as...
:root {
--ion-color-secondary: #006600;
--ion-color-secondary-rgb: 0,102,0;
--ion-color-secondary-contrast: #ffffff;
--ion-color-secondary-contrast-rgb: 255,255,255;
--ion-color-secondary-shade: #005a00;
--ion-color-secondary-tint: #1a751a;
}
The colour generator can be used to generate these for a base colour. It can't be done with SCSS because it needs to work at runtime. Solutions to support this are being worked on.
Adding Colours
New colours that are used throughout your application can be added, as an alternative to modifying a default colour.
Modifying the Background Colour or Text Colour
When modifying the background colour or text colour variable, a large set of stepped colours also need to be updated. An example is...
:root {
--ion-background-color: #ffffff;
--ion-background-color-rgb: 255, 255, 255;
--ion-text-color: #000000;
--ion-text-color-rgb: 0, 0, 0;
--ion-color-step-50: #f2f2f2;
--ion-color-step-100: #e6e6e6;
--ion-color-step-150: #d9d9d9;
--ion-color-step-200: #cccccc;
--ion-color-step-250: #bfbfbf;
--ion-color-step-300: #b3b3b3;
--ion-color-step-350: #a6a6a6;
--ion-color-step-400: #999999;
--ion-color-step-450: #8c8c8c;
--ion-color-step-500: #808080;
--ion-color-step-550: #737373;
--ion-color-step-600: #666666;
--ion-color-step-650: #595959;
--ion-color-step-700: #4d4d4d;
--ion-color-step-750: #404040;
--ion-color-step-800: #333333;
--ion-color-step-850: #262626;
--ion-color-step-900: #191919;
--ion-color-step-950: #0d0d0d;
}
These can be easily generated.
Global Application CSS Variables
A number of global application variables are available. These should be used where they can be. Examples include --ion-font-family, --ion-padding and --ion-margin. Those last two modify the values used by the utility attributes for padding and margin that were discussed above.
Global Grid CSS Variables
A number of global grid variables are available. These should be used where they can be. Examples include --ion-grid-columns and --ion-grid-padding-xl.
Component CSS Variables
The CSS Variables that a component accepts can be found in the Custom Properties section of its entry in the API Reference.
For example, see the Custom Properties for ion-button, such as --ripple-color or --color-activated.
Setting CSS Variables
To set global variables, use the src/theme/variables.scss file, and set them on the :root selector, such as...
:root {
/* Set the font family of the entire app */
--ion-font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "Roboto", sans-serif;
}
To set component variables, use the component selector, such as...
/* Set the color on all ion-button elements */
ion-button {
--color: #222;
}
CSS variables should be used to modify components where they are available.
Getting CSS Variables
To get a CSS variable, the var() CSS function should be used, which allows any number of fallback values, such as...
.fancy-button {
--background: var(--charcoal, #36454f);
}
Platform Styling
Platform specific styling should be changed using the .ios and .md selectors, such as:
.ios ion-badge {
text-transform: uppercase;
}
Global variables should be used for this where they are available, such as:
.ios {
--ion-background-color: #222;
}

Related

Is there a way to override the system defined color value in CSS?

I'd like color: red to automatically be rendered as color: #DB0000 by the browser. Instead of setting the style for "red" in our application as color: red, I want to use a different color than the system-defined definition of red. Our application uses a different "red" color than the standard setting for setting the color: red style in css. Other than creating a class and using that class where I need to set the style (I'm afraid developers could forget to use this class and instead set color: red), is there a way to automatically override the defined color for color: red and override it with my own setting of color: #DB0000?
No, there isn't a possibility like this in plain CSS.
However, in SASS and LESS (both CSS preprocessors) you can define varibles. So you can for example define #red1: #DB0000 as a variable and later on use color: #red1 or border-color: #red1 in as many CSS rules as you like.
That's not possible with CSS, but if you use SASS, you can create a macro to change the color, although that still might not work.
EDIT: After doing some spelunking on my own, there is a way to use variables in pure CSS (no SASS!):
:root {
--red: #DB0000; /* Define your custom value */
}
p {
color: var(--red); /* Reference your custom value.
All <p> elements will be given
a text color of #DB0000 */
}
Check out this CodePen
Source: https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_variables

Finding the Bootstrap variable that controls a specific CSS rule

I'm developing an application using Bootstrap 3. I use Sass/SCSS to customize the Bootstrap variables neatly.
I'm currently styling the "tabs" component and I can't seem to figure out if there is a specific variable that controls its text color, or if it's been inherited from somewhere else.
What's a good way to determine the "source" of a CSS rule that comes from Bootstrap? I use Chrome on OSX.
I just inspected the tab on the bootstrap site and searched for the .nav-tabs class in the bootstrap scss files. So in the _navs.scss file, search for "tabs" and you'll see the variables.
It looks like $nav-tabs-active-link-hover-color might be what you're looking for - it's the active tab's text color. The anchors in the non-active tabs appear to be default anchor tag color.
You can find that variable in the _variables.scss file. The variables are usually named according to the component that uses them (i.e. $nav-tabs-active-<whatever>).
// Active state, and its :hover to override normal :hover
&.active > a {
&,
&:hover,
&:focus {
color: $nav-tabs-active-link-hover-color; // ****** here
background-color: $nav-tabs-active-link-hover-bg;
border: 1px solid $nav-tabs-active-link-hover-border-color;
border-bottom-color: transparent;
cursor: default;
}
}

QT Stylesheet for HLine/VLine color

I'm pretty new to this Qt thing and its whole stylesheet system. My background of HTML/CSS helps a little to understand the system, but a lot of things just happens for no apparent reason....or don't happen.
Anyway, the mystery of the HLINE and the VLINE and how to change the lines' color is just a mystery for me. I learned from other questions and various fora that it's linked to the QFrame elements. And I can change the color of the line if I just use something like
QFrame
{
color: red;
}
But this of course changes the color of tons of other things that uses a QFrame as well. I could of course go into the HLINE element and put color: red; in there and that works fine, but my app requires that I put everything in a single stylesheet that gets loaded into the app. So styling individual elements is not an option.
A solution would look something like
QFrame HLine, QFrame VLine
{
color: red;
}
QFrame[frameShape="4"] /* QFrame::HLine == 0x0004 */
{
color: red;
}
QFrame[frameShape="5"] /* QFrame::VLine == 0x0005 */
{
color: green;
}
HLine and VLine are tricky to style. It's worth taking a look at the "Detailed Description" section of the documentation. For a quick fix, I found that this set of rules allows customizing the appearance of such lines via stylesheet in a reliable and relatively clean manner:
QFrame[frameShape="4"],
QFrame[frameShape="5"]
{
border: none;
background: red;
}
This works regardless of the frameShadow property, which otherwise affects their appearance and the effect of style rules. Keep in mind that the width of the lines are not 1px by default -- this can be changed using the min-width, max-width, min-height or max-height properties, as appropriate.
For a more detailed overview of my findings, read along.
Most QFrames have the QFrame::Plain frameShape by default, but HLine and VLine's default frameShape is QFrame::Sunken. This means that they are not really lines, but thin boxes that contain a mid-line that's used to provide the 3D effect. From the documentation:
The mid-line width specifies the width of an extra line in the middle of the frame, which uses a third color to obtain a special 3D effect. Notice that a mid-line is only drawn for Box, HLine and VLine frames that are raised or sunken.
If you set the frameShape to Plain, this midline is still visible, and can be styled with the color property (note: that's not a background-color or border-color!)
But this doesn't work for a HLine/VLine that's left with the default Sunken appearance. One way to fix this could be to set separate styles for Plain and Sunken QFrames by using attribute selectors with the decimal values of the property enums (which are described in the documentation in hehadecimal), like so:
/* Reference (from doc.qt.io/qt-5/qframe.html#types):
* - frameShape[4] --> QFrame::HLine = 0x0004
* - frameShape[5] --> QFrame::VLine = 0x0005
* - frameShadow[16] --> QFrame::Plain = 0x0010 (default for most widgets)
* - frameShadow[48] --> QFrame::Sunken = 0x0030 (default for HLine/VLine)
*/
QFrame[frameShape="4"][frameShadow="16"],
QFrame[frameShape="5"][frameShadow="16"]
{
...
}
QFrame[frameShape="4"][frameShadow="48"],
QFrame[frameShape="5"][frameShadow="48"]
{
...
}
but since the styles that work for HLine/VLine with QFrame::Sunken also work for those with QFrame::Plain, it's usually a waste to do so. I show them above for educational value only about how to use attribute selectors.
The best approach is to treat the QFrame as the box that it is, and either (1) set border-top or border-right coupled with a max-height: 0px (or max-width for a VLine), to ensure the inside of the box doesn't take up space in the layout; or (2) use a background color coupled with border: none (in which case, max-height/width should be 1 or larger, otherwise the QFrame is invisible). The latter is the solution I'd recommend, as shown in the first code block above.
Hope this helps!
According to QDarkStyleSheet issue, You could use:
QFrame[width="3"], QFrame[height="3]
These selectors, they seem to work cross-platform, and they are unlikely to change.
Probably better than using enum values as ints, as they are likely to change with Qt versions, and line styling are not, as they fulfill certain requirements.
but my app requires that i put everything in a single stylesheet that
gets loaded into the app.
You can use Conflict Resolution. Suppose that you have a QMainWindow object with lots of widgets on it . Set these style sheets for the maindionw style sheet :
QLabel#label{
background-color: rgb(255, 170, 255);
}
QPushButton#pushButton{
color: rgb(0, 0, 255);
}
QFrame#line{
background-color: rgb(0, 170, 255);
}
The first css just changes a QLabel name label on your mainwindow and set its back color to rgb(255, 170, 255). The next will change text color of a QPushButton named pushButton to (0,0,255);. The third one change property of a line.Lines are just a QFrame.
So the solution that I can offer is to place your css in a file and then load this file using QFile and QTextStream and then set the contents of the file for css of your main winodw or main widget using setStyleSheet ( const QString & styleSheet ) function. or If you are using creator just right click on your main window and select change stylesheet and then paste your css. But bear in mind that you should use conflict resolution.
You can leave Qt's hlines and build up your own very easy. For frames you want looks like hline add property "class" as "HLine" (for example), in designer or in c++ code:
frame->setProperty("class", "HLine")
.
Then, you can define in main view's or in global app stylesheet something like this:
QFrame.HLine {
border: none;
border-bottom: 2px solid red;
}
and you will get horizontal two pixels red line.

Create a variable in .CSS file for use within that .CSS file [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Avoiding repeated constants in CSS
We have some "theme colors" that are reused in our CSS sheet.
Is there a way to set a variable and then reuse it?
E.g.
.css
OurColor: Blue
H1 {
color:OurColor;
}
There's no requirement that all styles for a selector reside in a single rule, and a single rule can apply to multiple selectors... so flip it around:
/* Theme color: text */
H1, P, TABLE, UL
{ color: blue; }
/* Theme color: emphasis */
B, I, STRONG, EM
{ color: #00006F; }
/* ... */
/* Theme font: header */
H1, H2, H3, H4, H5, H6
{ font-family: Comic Sans MS; }
/* ... */
/* H1-specific styles */
H1
{
font-size: 2em;
margin-bottom: 1em;
}
This way, you avoid repeating styles that are conceptually the same, while also making it clear which parts of the document they affect.
Note the emphasis on "conceptually" in that last sentence... This just came up in the comments, so I'm gonna expand on it a bit, since I've seen people making this same mistake over and over again for years - predating even the existence of CSS: two attributes sharing the same value does not necessarily mean they represent the same concept. The sky may appear red in the evening, and so do tomatoes - but the sky and the tomato are not red for the same reason, and their colors will vary over time independently. By the same token, just because you happen to have two elements in your stylesheet that are given the same color, or size or positioning does not mean they will always share these values. A naive designer who uses grouping (as described here) or a variable processor such as SASS or LESS to avoid value repetition risks making future changes to styling incredibly error-prone; always focus on the contextual meaning of styles when looking to reduce repetition, ignoring their current values.
You can achieve it and much more by using Less CSS.
No, but Sass does this. It's a CSS preprocessor, allowing you to use a lot of shortcuts to reduce the amount of CSS you need to write.
For example:
$blue: #3bbfce;
$margin: 16px;
.content-navigation {
border-color: $blue;
color:
darken($blue, 9%);
}
.border {
padding: $margin / 2;
margin: $margin / 2;
border-color: $blue;
}
Beyond variables, it provides the ability to nest selectors, keeping things logically grouped:
table.hl {
margin: 2em 0;
td.ln {
text-align: right;
}
}
li {
font: {
family: serif;
weight: bold;
size: 1.2em;
}
}
There's more: mixins that act kind of like functions, and the ability to inherit one selector from another. It's very clever and very useful.
If you're coding in Ruby on Rails, it'll even automatically compile it to CSS for you, but there's also a general purpose compiler that can do it for you on-demand.
You're not the first to wonder and the answer is no. Elliotte has a nice rant on it: http://cafe.elharo.com/web/css-repeats-itself/. You could use JSP, or its equivalent, to generate the CSS at runtime.
CSS doesn't offer any such thing. The only solution is to write a preprocessing script that is either run manually to produce static CSS output based on some dynamic pseudo-CSS, or that is hooked up to the web server and preprocesses the CSS prior to sending it to the client.
That's not supported at the moment unless you use some script to produce the CSS based on some variables defined by you.
It seems, though, that at least some people from the browser world are working on it. So, if it really becomes a standard sometime in the future, then we'll have to wait until it is implemented in all the browsers (it will be unusable until then).
Since CSS does not have that (yet, I believe the next version will), follow Konrad Rudolphs advice for preprocesing. You probably want to use one that allready exists: m4
http://www.gnu.org/software/m4/m4.html
You're making it too complicated. This is the reason the cascade exists. Simply provide your element selectors and class your color:
h1 {
color: #000;
}
.a-theme-color {
color: #333;
}
Then apply it to the elements in the HTML, overriding when you need to use your theme colors.
<h1>This is my heading.</h1>
<h1 class="a-theme-color">This is my theme heading.</h1>
I've written a macro (in Visual Studio) that allows me to not only code CSS for named colors but to easily calculate shades or blends of those colors. It also handles fonts. It fires on save and outputs a separate version of the CSS file. This is in line with Bert Bos's argument that any symbol processing in CSS take place at the point of authoring, not not at the point of interpretation.
The full setup along with all the code would be a bit too complicated to post here, but might be appropriate for a blog post down the road. Here's the comment section from the macro which should be enough to get started.
The goals of this approach are as follows:
Allow base colors, fonts, etc. to be defined in a central location, so that an entire pallete or typographical treatment can be easily tweaked without having to use search/replace
Avoid having to map the .CSS extension in IIS
Generate garden-variety text CSS files that can be used, for example, by VisualStudio's design mode
Generate these files once at authoring time, rather than recalculating them every time the CSS file is requested
Generate these files instantly and transparently, without adding extra steps to the tweak-save-test workflow
With this approach, colors, shades of colors, and font families are all represented with shorthand tokens that refer to a list of values in an XML file.
The XML file containing the color and font definitions must be called Constants.xml and must reside in the same folder as the CSS files.
The ProcessCSS method is fired by EnvironmentEvents whenever VisualStudio saves a CSS file. The CSS file is expanded, and the expanded, static version of the file is saved in the /css/static/ folder. (All HTML pages should reference the /css/static/ versions of the CSS files).
The Constants.xml file might look something like this:
<?xml version="1.0" encoding="utf-8" ?>
<cssconstants>
<colors>
<color name="Red" value="BE1E2D" />
<color name="Orange" value="E36F1E" />
...
</colors>
<fonts>
<font name="Text" value="'Segoe UI',Verdana,Arial,Helvetica,Geneva,sans-serif" />
<font name="Serif" value="Georgia,'Times New Roman',Times,serif" />
...
</fonts>
</cssconstants>
In the CSS file, you can then have definitions like:
font-family:[[f:Text]];
background:[[c:Background]];
border-top:1px solid [[c:Red+.5]]; /* 50% white tint of red */
See also Avoiding repeated constants in CSS. As Farinha said, a CSS Variables proposal has been made, but for the time being, you want to use a preprocessor.
You can use mutliple classes in the HTML element's class attribute, each providing part of the styling. So you could define your CSS as:
.ourColor { color: blue; }
.ourBorder { border: 1px solid blue; }
.bigText { font-size: 1.5em; }
and then combine the classes as required:
<h1 class="ourColor">Blue Header</h1>
<div class="ourColor bigText">Some big blue text.</div>
<div class="ourColor ourBorder">Some blue text with blue border.</div>
That allows you to reuse the ourColor class without having to define the colour mulitple times in your CSS. If you change the theme, simply change the rule for ourColour.
This may sound like insanity, but if you are using NAnt (or Ant or some other automated build system), you can use NAnt properties as CSS variables in a hacky way. Start with a CSS template file (maybe styles.css.template or something) containing something like this:
a {
color: ${colors.blue};
}
a:hover {
color: ${colors.blue.light};
}
p {
padding: ${padding.normal};
}
And then add a step to your build that assigns all the property values (I use external buildfiles and <include> them) and uses the <expandproperties> filter to generate the actual CSS:
<property name="colors.blue" value="#0066FF" />
<property name="colors.blue.light" value="#0099FF" />
<property name="padding.normal" value="0.5em" />
<copy file="styles.css.template" tofile="styles.css" overwrite="true">
<filterchain>
<expandproperties/>
</filterchain>
</copy>
The downside, of course, is that you have to run the css generation target before you can check what it looks like in the browser. And it probably would restrict you to generating all your css by hand.
However, you can write NAnt functions to do all sorts of cool things beyond just property expansion (like generating gradient image files dynamically), so for me it's been worth the headaches.
CSS does not (yet) employ variables, which is understandable for its age and it being a declarative language.
Here are two major approaches to achieve more dynamic style handling:
Server-side variables in inline css
Example (using PHP):
<style> .myclass{color:<?php echo $color; ?>;} </style>
DOM manipulation with javascript to change css client-side
Examples (using jQuery library):
$('.myclass').css('color', 'blue');
OR
//The jsvarColor could be set with the original page response javascript
// in the DOM or retrieved on demand (AJAX) based on user action.
$('.myclass').css('color', jsvarColor);

CSS (Stylesheet) organization and colors

I just finished a medium sized web site and one thing I noticed about my css organization was that I have a lot of hard coded colour values throughout. This obviously isn't great for maintainability. Generally, when I design a site I pick 3-5 main colours for a theme. I end up setting some default values for paragraphs, links, etc... at the beginning of my main css, but some components will change the colour (like the legend tag for example) and require me to restyle with the colour I wanted. How do you avoid this? I was thinking of creating separate rules for each colour and just use those when I need to restyle.
i.e.
.color1 {
color: #3d444d;
}
One thing I've done here is break out my palette declarations from other style/layout markup, grouping commonly-colored items in lists, e.g.
h1 {
padding...
margin...
font-family...
}
p {
...
}
code {
...
}
/* time passes */
/* these elements are semantically grouped by color in the design */
h1, p, code {
color: #ff0000;
}
On preview, JeeBee's suggestion is a logical extension of this: if it makes sense to handle your color declarations (and, of course, this can apply to other style issues, though color has the unique properties of not changing layout), you might consider pushing it out to a separate css file, yeah. This makes it easier to hot-swap color-only thematic variations, too, by just targeting one or another colorxxx.css profile as your include.
That's exactly what you should do.
The more centralized you can make your css, the easier it will be to make changes in the future. And let's be serious, you will want to change colors in the future.
You should almost never hard-code any css into your html, it should all be in the css.
Also, something I have started doing more often is to layer your css classes on eachother to make it even easier to change colors once... represent everywhere.
Sample (random color) css:
.main_text {color:#444444;}
.secondary_text{color:#765123;}
.main_color {background:#343434;}
.secondary_color {background:#765sda;}
Then some markup, notice how I am using the colors layer with otehr classes, that way I can just change ONE css class:
<body class='main_text'>
<div class='main_color secondary_text'>
<span class='secondary color main_text'>bla bla bla</span>
</div>
<div class='main_color secondary_text>
You get the idea...
</div>
</body>
Remember... inline css = bad (most of the time)
See: Create a variable in .CSS file for use within that .CSS file
To summarize, you have three basic option:
Use a macro pre-processor to replace constant color names in your stylesheets.
Use client-side scripting to configure styles.
Use a single rule for every color, listing all selectors for which it should apply (my fav...)
I sometimes use PHP, and make the file something like style.css.php.
Then you can do this:
<?php
header("Content-Type: text/css");
$colour1 = '#ff9';
?>
.username {color: <?=$colour1;?>; }
Now you can use that colour wherever you want, and only have to change it in one place. This also works for values other then colours of course.
Maybe pull all the color information into one part of your stylesheet. For example change this:
p .frog tr.mango {
color: blue;
margin: 1px 3em 2.5em 4px;
position: static;
}
#eta .beta span.pi {
background: green;
color: red;
font-size: small;
float: left;
}
// ...
to this:
p .frog tr.mango {
color: blue;
}
#eta .beta span.pi {
background: green;
color: red;
}
//...
p .frog tr.mango {
margin: 1px 3em 2.5em 4px;
position: static;
}
#eta .beta span.pi {
font-size: small;
float: left;
}
// ...
You could have a colours.css file with just the colours/images for each tag in.
Then you can change the colours just by replacing the file, or having a dynamically generated CSS file, or having different CSS files available and selecting based upon website URL/subfolder/property/etc.
Or you can have colour tags as you write, but then your HTML turns into:
<p style="body grey">Blah</p>
CSS should have a feature where you can define values for things like colours that you wish to be consistent through a style but are defined in one place only. Still, there's search and replace.
So you're saying you don't want to go back into your CSS to change color values if you find another color 'theme' that might work better?
Unfortunately, I don't see a way around this. CSS defines styles, and with color being one of them, the only way to change it is to go into the css and change it.
Of course, you could build yourself a little program that will allow you to change the css file by picking a color wheel on a webpage or something, which will then write that value into the css file using the filesystemobject or something, but that's a lot more work than required for sure.
Generally it's better to just find and replace the colours you are changing.
Anything more powerful than that will be more complex with few benefits.
CSS is not your answer. You want to look into an abstraction on top of CSS like SASS. This will allow you to define constants and generally clean up your css.
Here is a list of CSS Frameworks.
I keep a list of all the colors I've used at the top of the file.
When the CSS is served by a server-side script, eg. PHP, usually coders make the CSS as a template file and substitute the colors at run-time. This might be used to let users choose a color model, too.
Another way, to avoid parsing this file each time (although cache should take care of that), or just if you have a static site, is to make such template and parse it with some script/static template engine before uploading to the server.
Search/replace can work, except when two initially distinct colors end up being the same: hard to separate them again after that! :-)
If I am not mistaken, CSS3 should allow such parametrization. But I won't hold my breath until this feature will be available in 90% of browsers surfing the Net!
I like the idea of separating the colour information into a separate file, no matter how I do it. I would accept multiple answers here if I could, because I like Josh Millard's as well. I like the idea of having separate colour rules though because a particular tag might have different colours depending on where it occurs. Maybe a combination of both of these techniques would be good:
h1, p, code {
color: #ff0000;
}
and then also have
.color1 {
color: #ff0000;
}
for when you need to restyle.
This is where SASS comes to help you.

Resources