WordPress conditionals not working

The problem is that you’re wrapping your add_action() calls inside of the conditionals, but at the point at which those add_action() calls are executed, neither the query nor the query conditionals are available yet.

Solution: put the conditionals inside the callbacks:

function faq_start_shortcode( $atts, $content = null ) {
    if ( is_single() || is_page() ) {
        return '<div id="accordion">';
    }
}

function faq_question_shortcode( $atts, $content = null ) {
    if ( is_single() || is_page() ) {
        return '<div class="accordionButton">' . $content . '</div>';
    }
}

function faq_answer_shortcode( $atts, $content = null ) {
    if ( is_single() || is_page() ) {
        return '<div class="accordionContent">' . $content . '</div>';
    }
}

function faq_end_shortcode( $atts, $content = null ) {
    if ( is_single() || is_page() ) {
        return '</div>';
    }
}


add_shortcode('faqstart', 'faq_start_shortcode');
add_shortcode('question', 'faq_question_shortcode');
add_shortcode('answer', 'faq_answer_shortcode');
add_shortcode('faqend', 'faq_end_shortcode');

(p.s. you can use is_singular() as a shorthand for ( is_single() || is_page() ).