Softforks restrict block acceptance rules in comparison to earlier versions.
That way, any blocks considered valid by the newer version are still valid in the old version. If at least 51% of the mining power shifts to the new version, the system self-corrects. (If less than 51% switch to the new version, it behaves like a hardfork though.)
Blocks created by old versions of BitcoinCore that are invalid under the new paradigm might commence a short-term "old-only fork". Eventually they would be overtaken by a fork of the new paradigm, as the hashing power working on the old paradigm would be smaller ("only old versions") than on the new paradigm ("accepted by all versions").
Hardforks ease block acceptance rules making previously invalid blocks valid in the new version. Older versions will not accept the new blocks, causing a fork which will not mend unless everyone upgrades to the new version.