Dubsado’s digital contract featured is one of the MANY amazing features but you know the one thing that always bugs me as a Dubsado certified specialist? The fact that you can only have lists as bullet points or numbers but without the option of multi-level numbered listing.
I’m talking about the 1.1. 1.2. 1.3. styling that everyone loves to use in their contracts.
I’ve setup over 50+ businesses in Dubsado and this is always an issue in Dubsado contracts, these business invest in a lawyers to put together their contract and all clauses use the multi level number feature.
BUT I have a solution that instantly creates this within your Dubsado contracts.
All you have to do is copy the code below and pop it into the “Edit CSS” button within the “form Styling” on your contract sidebar.
Here is the CSS to copy & paste:
ol {
list-style-type: none; /* Remove default list styles */
counter-reset: item; /* Initialize the counter */
margin: 0;
padding: 0;
}
ol > li {
display: table; /* Make list items behave like table rows */
counter-increment: item; /* Increment the counter for each list item */
margin-bottom: 0.6em; /* Space between list items */
}
ol > li:before {
content: counters(item, ".") ". "; /* Generate the multi-level numbering */
display: table-cell; /* Align the number like a table cell */
padding-right: 0.6em; /* Space between number and content */
font-weight: bold; /* Make the number bold */
}
li ol > li {
margin: 0; /* Remove margin for nested list items */
}
li ol > li:before {
content: counters(item, ".") " "; /* Continue multi-level numbering */
}
Let’s break down the CSS, section by section, to understand what each part is doing:
1. ol { list-style-type: none; counter-reset: item; margin: 0; padding: 0; }
list-style-type: none;: This removes the default list style, which typically would be numbers or bullets. This allows custom numbering to be applied instead.counter-reset: item;: This resets the CSS counter nameditem. This is essential to start the numbering sequence from the beginning whenever a new ordered list (<ol>) is encountered.margin: 0;: This removes the default margin around the ordered list.padding: 0;: This removes the default padding inside the ordered list.
2. ol > li { display: table; counter-increment: item; margin-bottom: 0.6em; }
display: table;: This makes each list item (<li>) behave like a table-row, allowing the::beforepseudo-element to behave like a table-cell, aligning numbers and content cleanly.counter-increment: item;: This increments theitemcounter by 1 for each list item (<li>). This ensures that each list item is numbered sequentially.margin-bottom: 0.6em;: This adds some space (0.6 times the current font size) between the list items to improve readability.
3. ol > li:before { content: counters(item, “.”) “. “; display: table-cell; padding-right: 0.6em; font-weight: bold; }
content: counters(item, ".") ". ";: This generates the content for the::beforepseudo-element. Thecounters(item, ".")part combines the values of theitemcounter from all levels of nesting, separated by dots (e.g.,1.1,1.2). The additional". "appends a final dot and a space to the number.display: table-cell;: This makes the::beforepseudo-element behave like a table-cell, allowing it to align with the main content of the list item.padding-right: 0.6em;: This adds some padding to the right of the generated number, creating space between the number and the list item content.font-weight: bold;: This makes the generated number bold to differentiate it visually from the content of the list item.
4. li ol > li { margin: 0; }
margin: 0;: This removes any margin around nested list items. This ensures that nested lists align neatly without extra spacing that could disrupt the structure.
5. li ol > li:before { content: counters(item, “.”) ” “; }
content: counters(item, ".") " ";: Similar to the previouscontentproperty, this generates the multi-level numbering for nested list items. The difference here is that there is no trailing dot or extra space after the number—just the number itself followed by a single space. This keeps the nested numbers consistent with their parent list items.
20 Free Dubsado Portal Templates for Desktop & Mobile
20 free templates to stay on brand & WOW your clients – it really does add to that 5* client experience.
Conclusion
Dubsado is one of the best CRMs out there for service based businesses that work with clients one to one. It keeps all your clients (known as projects) in one place so you can streamline onboarding & offboarding processes. This includes booking in consultations, sending call reminder emails, sending contracts, invoices, proposals, recurring payments and more.
Get 30% off your first month or even year with discount code sarahworboyes or click here to sign up and get your discount with a free trial.
If you are looking for Dubsado proposal inspiration check out my Dubsado proposal templates by clicking here.




