0

I'm trying to use the default bootstrap css (app.css) that ships with Laravel to style a section of my page - specifically, the form section of my registration page.

I don't want to include app.css in my html header as it gives me undesired effect on other parts of the page. So I want it to style only my html forms within the page.

Currently, I've used either the asset() or HTML::style() methods like this within my form section:

@section('form')
<style> @import "{{ asset('css/app.css') }}"; </style>
<form>...</form>
@endsection

OR

@section('form')
{{ HTML::style('css/app.css') }}
<form>...</form>
@endsection

Both method loads the style correctly, but affects the entire page instead of only the form elements.

I tried using the ViewComposer class to solve this problem by setting a variable in ViewComposer to my desired style - returning it only when I request the required view:

class ViewComposer
{
  public function compose(View $view)
  {
    $data = [];
    switch($view->getName())
    {
      ...
      case 'sections.register':
        $this->data = ['style'=>"<style> @import \"". asset('css/app.css') . "\"; </style>"];
        break;
    }

    return $view->with($this->data);
  }
}

However, when I render the sections.register sub-view, I get the style variable like this:

@section('form')
{{ $style ?? '' }}
<form>...</form>
@endsection

the output on the browser is not parsed as css but displayed as-is:

<style> @import "{{ asset('css/app.css') }}"; </style>

So, is there a way I can parse external css for only a given view section within the html page and can it be achieved using the ViewComposer class?

UPDATE: I was trying a few things and used this:

@section('form')
{!! $style ?? '' !!}
<form>...</form>
@endsection

The css is parsed but still applied to the entire page. I still need it applied to only the form section.

Udo E.
  • 2,665
  • 2
  • 21
  • 33

2 Answers2

1

1. One option is to copy only the css you need and paste it into custom css and make a different layout for that view. But that can be tedious work as you said.

2. Another option is to prefix you app.css file. There is a software that can do that here is the tutorial. So if you prefix whole css file with for example: .laravel-app then you can wrap anything that you would like to be styled by app.css like this:

<div class="laravel-app">
<!-- Everything in here will be styled by app.css -->
</div>

This will help you in the long run with your project.

  • I understand what this is doing. But it's the opposite of what I want to achieve. Here, you are preventing a local element within your markup from inheriting the global css of the page. What I want is to apply an external css locally so that only a local element is affected and it isn't applied globally. I'm aware I can achieve this using embedded style tags and inline css. But I want this done using an external css style sheet. – Udo E. Jun 28 '19 at 15:29
  • Im really sorry I misunderstood what you were trying to achieve. Maybe another option is to get the css from app.css for the form only (maybe easier using CSS used chrome plugin) and using different layout for that view? – Denis Ćerić Jun 28 '19 at 16:14
  • Thanks @Denis Ceric. Yes, It's the approach I've temporarily adopted. Though I had to use Visual Studio Code editor to get the needed styles into another style sheet. But it is really tedious. I'll try the Chrome plugin next time. But it would be really nice if I get a proper answer so I don't keep doing this cut-and-paste all the time. – Udo E. Jun 28 '19 at 16:28
  • 1
    I understand, please check out my updated answer. I hope it is helpful. – Denis Ćerić Jun 28 '19 at 16:50
  • Thanks Dennis, though your answer was not straight forward, it gave me a clue to the right answer – Udo E. Jun 30 '19 at 16:57
0

First of all, importing or loading css per-view will be bad for the performance of the application. So, using View Composer to load in css is not advisable. I took a cue from Denis Ćerić's answer, though it wasn't clear at first glance.

Also, the accepted answer on this post made things a little clearer.

The right way to achieve this is to use a css preprocessor. Popular ones are less and sass. I used sass because it is currently adopted by Laravel.

I installed sass on my windows machine following the instructions here.

Create a new scss file: app-custom.scss in the same folder as app.css.

Modify app-custom.scss using nested imports:

.app-form
{
    @import 'app';
}

Generate app-custom.css using the sass command on Windows command line:

sass app-custom.scss app-custom.css

Change the class of your form to app-form:

@section('form')
<form class='app-form'>...</form>
@endsection

Include app-custom.css in your header using link tag:

<head>
    <link href="{{ asset('css/app-custom.css') }}" rel="stylesheet">
</head>

and you are done.

HINT: if you want to use the style in app.css for multiple separate sections of your page, you can still achieve this from a single scss file. Just include the classes of each section in your scss file like this:

.section-1, .section-2, .section-3
{
    @import 'app';
}
Udo E.
  • 2,665
  • 2
  • 21
  • 33