There are two separate factors going on here. First, the intervals between blocks are not perfectly spaced, but rather have some randomness with an average spacing of the chain's target-block-time parameter. Second, a transaction can take longer or shorter to confirm based on when it is broadcast, and how long it takes to propagate, to whichever node ends up building the next block in the chain. It could arrive a split second before, and therefore be confirmed quickly. Or it could arrive a split second after, and then have to wait for an entire block interval before it is confirmed.