2

I'm working on a web interface in ASP.NET. If it matters, I'm using the XHTML 1.0 Transitional doctype.

This website has a masterpage thing going, and that's where the problem came in. When I used a real absolute path for the CSS link in the header, everything was fine. But then when I tried to switch it to tilde notation, all the styling broke.

Here's a fragment of the original master page, which worked fine:

<head>
    <title>Account Information</title>
    <link href="/css/main.css" rel="stylesheet" type="text/css" />
</head>
<body>
...
</body>

But then we found out that this account thing is going to be an application that doesn't live on the server root, so we had to make changes.

<head>
    <title>Account Information</title>
    <link runat="server" href="~/css/main.css" rel="stylesheet" type="text/css" />
</head>
<body>
...
</body>

Now, those same changes (adding runat="server" and a tilde) worked just FINE everywhere else in the page, but this one didn't. When I looked at the output, it was not resolving the tilde, so the link was actually pointing at "myserver.net/~/css/main.css", which obviously isn't going to work.

Next I tried using ResolveURL, like so:

<link runat="server" href="<% =ResolveURL("~/css/main.css") %>" rel="stylesheet" type="text/css" />

Visual Studio wouldn't even compile that. It didn't even know what ResolveURL meant (as a test, I stuck the same code several other places, including the page title right there next to the link tag, and it worked fine everywhere else).

I did eventually get it to work by giving the link an ID and setting the href in the code-behind:

--Master page--
<link id="StyleLink" runat="server" rel="stylesheet" type="text/css" />

--Masterpage codebehind file--
StyleLink.Attributes.Add("href", ResolveUrl("~/css/main.css"));

But I'm left wondering why I had to spend two hours fighting with this. Why didn't the standard ~ notation work in the first place? I googled around for a while but I couldn't find anything particularly relevant; the closest I could find was a discussion of ~ notation failing when it was in a sub-master page.

TylerH
  • 20,799
  • 66
  • 75
  • 101
Darth Pseudonym
  • 145
  • 1
  • 5
  • 2
    ResolveURL is different than ResolveUrl – Adrian Iftode Nov 01 '11 at 22:10
  • I had to retype it to put it in the message. It was correct in the original code. – Darth Pseudonym Nov 02 '11 at 14:25
  • 1
    Tilde ("~/") notation is not standard to CSS - it's standard to Microsoft/ASP.Net. Your browser and CSS have no concept of the application root. So either in the ASPX or code-behind, you need to dereference it to an absolute URL so that the browser can find it. – GalacticCowboy Nov 02 '11 at 16:13

3 Answers3

5

This works in the Master Page in front of me right now:

<head runat="server">
     <link runat="server" href="~/styles/main.css" rel="stylesheet" type="text/css" />
</head>

For a Page in the root of the application, this translates out to the HTML as this:

<link href="styles/main.css" rel="stylesheet" type="text/css" />

For a Page in a folder off the root, here's what it looks like:

<link href="../styles/main.css" rel="stylesheet" type="text/css" />

(Both pages use that Master, obviously)


Alternative approach

Store the path to the CSS file in the web config, and alter it upon deployment.
You can even use Web Config Transformations to change it automatically based on the build type.

Graham
  • 3,217
  • 1
  • 27
  • 29
  • what I was stating in my answer was that if you have a master page in a subfolder and not the root directory then if you use the ~ in the master page to reference the root it will remove all of the styling because it is calling the incorrect location. – CBRRacer Nov 02 '11 at 18:18
1

I am guessing that this may be a problem with the scope of the application. In other words when you run <link rel='stylesheet' href='~/css/base.css' id='id' runat='server'> the application may be returning something like this

http://www.mydirectory.com/includes/masterpages/css/base.css

and you want a return something like this

http://www.mydirectory.com/css/base.css

since the ~ gets the application root directory and appends it you may be getting an error on where you master page is if it is not saved in the root directory.

Here's a link to a SO question that I referenced to explain the problem. slash(/) vs tilde slash (~/) in style sheet path in asp.net

I have no idea why it wouldn't compile other than a possibly unclosed quotation mark in the link tag ie. <link type='text/css" href="..." runat="server" /> notice the single quote in the type vs. the double quote close. I have done that on occasion but I am just guessing here. I checked it on my and dropping in the ~ with a runat server doesn't cause a compile time error for me.

Community
  • 1
  • 1
CBRRacer
  • 4,649
  • 1
  • 23
  • 27
  • I don't think I see how the life cycle comes into this discussion. When I put ~/ in the **link** tag it doesn't work; if I put the same ~/ in the **title** tag right next to it, it works fine. Or anywhere else in the page. – Darth Pseudonym Nov 02 '11 at 14:28
  • For what it's worth, I'm using MVS 2010, and everywhere else on the page, starting out with the server tags (<%) and starting to type brings up the little window with various function calls listed (Is that called 'intellisense'? I can't remember the right name.) When I did the same in the link tag, I got no list of options, and I couldn't reference public variables from the page's class. It's like the link tag exists in a universe of its own. – Darth Pseudonym Nov 02 '11 at 14:34
0

I had links to CSS files in the master page using the following syntax

 <link  href="~/bm/Styles/Site.css" rel="stylesheet" type="text/css" />

The path resolved correctly in Chrome and Firefox, but not in IE9. The following syntax works fine in all three browsers. Notice the id and runat entries.

<link id="siteCss" runat="server"
      href="~/bm/Styles/Site.css" rel="stylesheet" type="text/css" />
Danny
  • 11
  • 1