Textile labeling looks like design work and reads like a serialization format. The rules in 16 CFR part 303 specify field order, a threshold, a catch-all bucket, a required placement for one field, and a rendering constraint. There is also a property you cannot test in a unit test without a physical sample, which is the reason this post exists.
The fields, in the order the rule gives them
Section 303.16(a) lists three required members and permits them on one label or several, including the care label required by 16 CFR part 423, as long as the combination is not misleading.
type FiberLine = {
genericName: string; // generic name, not a marketing name
percentByWeight: number;
bucket: "declared" | "other-fiber";
};
type TextileLabel = {
fibers: FiberLine[]; // 303.16(a)(1)
responsibleParty: // 303.16(a)(2) + 303.19
| { kind: "businessName"; value: string }
| { kind: "rn"; value: string } // registered identification number
| { kind: "houseMark"; value: string },
processedOrManufacturedIn: string; // 303.16(a)(3) + 303.33(a)(1)
};
The content rule has three numeric ideas hiding in prose. Fibers at 5 percent or more are declared by generic name with their percentage by weight. Anything below that shares the other-fiber wording, and the standard's own arrangement requirement puts that wording last. What remains is sorted by weight share, descending.
const OTHER_FIBER_THRESHOLD = 5;
export function serializeFibers(fibers: FiberLine[]): string {
const declared = fibers
.filter((f) => f.bucket === "declared" && f.percentByWeight >= OTHER_FIBER_THRESHOLD)
.sort((a, b) => b.percentByWeight - a.percentByWeight); // order of predominance
const others = fibers.filter((f) => f.bucket === "other-fiber");
const head = declared.map((f) => `${f.percentByWeight}% ${f.genericName}`);
if (others.length) {
const sum = others.reduce((n, f) => n + f.percentByWeight, 0);
head.push(`${sum}% other fibers`); // always last
}
return head.join(", ");
}
A comparator that sorts ascending, or that appends the other-fiber bucket before sorting, produces a string with every correct number and an arrangement the rule does not allow.
The constraint a renderer can break
Section 303.16(b) is a typography requirement, not a suggestion: required content has to be legible, conspicuous and easy for a buyer to reach, and the fiber lines must render at one type size with one level of prominence. A label template that renders the primary fiber larger than the secondary fiber fails on the last clause even though the sorted string is right.
export function assertEqualTypeScale(label: HTMLElement) {
const spans = [...label.querySelectorAll("[data-fiber-part]")];
const sizes = new Set(spans.map((s) => getComputedStyle(s).fontSize));
const weights = new Set(spans.map((s) => getComputedStyle(s).fontWeight));
if (sizes.size > 1 || weights.size > 1) {
throw new Error("fiber content rendered with mixed type scale");
}
}
Placement has one hard rule and it is per field. Section 303.15(b) requires the country of origin disclosure on the front side of the label, always, and for garments with a neck, the origin label belongs at the middle of the inside neckline, between the shoulder seams or beside a label already there. Fiber content and the responsible party name or RN may share that label or sit on another conspicuous, readily accessible label inside or outside the product. So the origin field is the one a template must never move to a reverse side.
The property no unit test can cover
Section 303.15(a) requires a securely attached, conspicuous label with durability to stay on the product and its package across distribution, a sale, a resale and the last leg to the buyer. That last stretch is the specification, and it is measured on a garment, not on a string.
label attachment checks, run on physical samples:
1 pull test on the sewn label, inspected after the cycle rather than before it
2 one garment held in its polybag for a week, one through a pick-and-pack loop
3 neck placement read on a worn garment, not on a flat table
4 legibility check under warehouse lighting, where pale tint on dark ground disappears
5 claim check: "100%" only when that part is wholly one fiber (303.27),
and always next to the correct generic name
Two of these fail in normal production. A heat transfer that lifts at a hem passes a visual check and fails check 2. A fiber statement printed in a light gray on charcoal passes the data check and fails check 4.
Floor space across our China facilities reads 13,000 square meters in Suzhou, then 8,000 in Dongguan, then 3,000 in Shenzhen, and apparel receipts are where a mixed type scale shows up first. We publish no rates and no transit promises in this pipeline, and none of the fields above come from a service level. They come from 16 CFR part 303. FulfillNexa by SBT (fulfillnexa.com) runs receiving and outbound handling for sellers shipping apparel from these sites.
Top comments (0)