I have a general purpose Couple class that serializes two generic properties like a tuple.
In the inspector a custom property drawer packs them in a single line.
I implemented it using IMGUI, where the label looks like the built in labels and the input fields are aligned with the input fields of the built in properties.
Now I want to migrate to UI Toolkit and got it working in principle, but I can't get the fields to always align with the built in ones.
My progress so far:
I found out here that the unity-base-field__aligned uss class is responsible to stretch the width of the label to create the alignment.
I tried to replicate the element tree structure and applied classes, but I guess the unity-base-field__aligned class only works for subclasses of BaseField<T>.
Moreover, this seems to compute a width value in some script and apply it inline, but I would prefer a solution using uss styles and classes.
The unity-base-field__label class sets a min-width to the label, which produces the desired result if the Inspector panel is small enough.
Here's my code:
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine;
using UnityEngine.UIElements;
[CustomPropertyDrawer(typeof(Couple<,>))]
public class CoupleEditor : PropertyDrawer {
public override VisualElement CreatePropertyGUI(SerializedProperty property) {
// Create property container element
var container = new VisualElement();
container.style.flexDirection = FlexDirection.Row;
// Create label
var label = new Label(property.displayName);
label.AddToClassList("unity-base-field__label"); // sets min-width to 120px
// Create input container
var input = new VisualElement();
input.style.flexDirection = FlexDirection.Row;
input.style.flexGrow = 1f;
// Create property fields
var item1 = new PropertyField(property.FindPropertyRelative(nameof(Couple<int, int>.Item1)), "");
var item2 = new PropertyField(property.FindPropertyRelative(nameof(Couple<int, int>.Item2)), "");
item1.style.flexGrow = 1f;
item2.style.flexGrow = 1f;
// Add fields to the container
container.Add(label);
input.Add(item1);
input.Add(item2);
container.Add(input);
return container;
}
// For reference: This is the working IMGUI version
public override void OnGUI(Rect rect, SerializedProperty property, GUIContent label) {
// Using BeginProperty / EndProperty on the parent property means that
// prefab override logic works on the entire property.
_ = EditorGUI.BeginProperty(rect, label, property);
// Draw label
rect = EditorGUI.PrefixLabel(rect, GUIUtility.GetControlID(FocusType.Passive), label);
// Disable indentation for inline fields
var indent = EditorGUI.indentLevel;
EditorGUI.indentLevel = 0;
// Calculate rects
var fieldGap = 8f;
var fieldWidth = (rect.width - fieldGap) / 2f;
var rect1 = new Rect(rect.x, rect.y, fieldWidth, rect.height);
var rect2 = new Rect(rect.x + fieldWidth + fieldGap, rect.y, fieldWidth, rect.height);
// Draw fields - pass GUIContent.none to each so they are drawn without labels
_ = EditorGUI.PropertyField(rect1, property.FindPropertyRelative(nameof(Couple<int, int>.Item1)), GUIContent.none);
_ = EditorGUI.PropertyField(rect2, property.FindPropertyRelative(nameof(Couple<int, int>.Item2)), GUIContent.none);
// Restore indent
EditorGUI.indentLevel = indent;
EditorGUI.EndProperty();
}
}

I had the same problem a while back so I reversed engineered the USS that they use by just copy and pasting all the class USS and finetuning it. I'm not 100% sure if this works all the time since I haven't used it in production. But it might get you where you need to go.
I made an example that can be found here: https://github.com/LiekeVanmulken/Unity-UIToolkit-Base-Field-Example/
The USS used to style a base field:
I commented what wasn't necessary but was in the classes. Just to keep track of what was in there. This contains mainly cursors and colors.