Debe poner la verificación de usuario en la unión, no en la condición donde, como por ejemplo:
SELECT c.course_id,l.topic,l.id,l.vid_duration,p.*
FROM courses c
LEFT JOIN lessons l ON l.course_id=c.course_id
LEFT JOIN progress p ON l.id = p.lesson_id and p.user_id = :userid
WHERE c.slug = :course
La razón para hacer esto es que JOINS usa la "unión izquierda" (que es implícitamente una unión externa). Este tipo de unión significa que si la condición funciona, devuelve todos los datos de columna para esa tabla para esa fila... condición no funciona, devolverá todos los datos de las tablas mencionadas anteriormente, pero para la tabla mencionada en la fila, devolverá NULLS para todas esas columnas.
Me disculpo por esa descripción, ya que es difícil poner en palabras exactamente cómo funciona una unión externa (o izquierda) compleja sin tener demasiadas palabras.