Restrict a users permission to only edit 'translatable' fields on a specific site? We would like to have a 'translators' user group, where the members can edit only the 'translatable' fields, but not the non translatable things (images, categories etc).

May be i missed something, but giving users permission to edit a specific site lets them edit all attributes.

Is there a way (permission/plugin/code snippet/best practice) to achieve that?

Thanks.

Thinking of writing a custom validation comparing old to new, or hiding/disabling fields via specific css.
Of course you can just remove the fields via CSS/JS but you could as well remove those fields from the visible layout from the beginning
Craft::$app-&gt;getView()-&gt;hook(
/**
 * @param array $context
 */
    'cp.entries.edit',
    function(array &amp;$context) {
        /** @var Section $section */
        $section = $context['section'];

        /** @var \craft\models\EntryType $entryType */
        $entryType = $context['entryType'];

        /** @var Entry $entry */
        $entry = $context['entry'];
        /**
         * Array of field handles you want to remove
         */
        $fieldsYouWantToRemove = [
            'relation',
            'tag',
            'category'
        ];

        // include certain conditions you like, either by registering custom permissions and do
        // Craft::$app-&gt;getUser()-&gt;checkPermission('myFancyPermission');
        // or just search for the current users groups
        // Craft::$app-&gt;getUser()-&gt;getIdentity()-&gt;getGroups();
        if($entry-&gt;siteId === 4 &amp;&amp; $section-&gt;handle === 'insertYourSectionHandle' &amp;&amp; $entryType-&gt;handle === 'yourEntryTypeHandle'){
            // grab all the fields in the layout
            foreach ($entryType-&gt;getFieldLayout()-&gt;getTabs() as $tab){
                /** @var \craft\base\Field[] $fields */
                $fields = $tab-&gt;getFields();
                foreach ($fields as $key =&gt; $field){
                    // check if the fields handle is forbidden
                    if(in_array($field-&gt;handle, $fieldsYouWantToRemove, true) === true){
                        // remove the field
                        unset($fields[$key]);
                    }
                }
                // set the fields back
                $tab-&gt;setFields($fields);
            }    
        }
    }
);

'cp.entries.edit' is a hook that enables you to manipulate all variables in the given context, so you check if the entry has a certain type and is in a certain section and remove all the fields from the tabs that you don't want to show.
You can register custom permissions for each field, for each site or you can even use events to check if the content has changed if you really want to make sure they didn't manipulate the HTML
edit
You can as well check for the translation setting in the field
if($field-&gt;translationMethod === Field::TRANSLATION_METHOD_SITE){
    unset($fields[$key]);
}

or
if($field-&gt;translationMethod !== Field::TRANSLATION_METHOD_NONE){
    unset($fields[$key]);
}

Whatever you need